diff --git a/app/pom.xml b/app/pom.xml
index db040232..47a2b725 100644
--- a/app/pom.xml
+++ b/app/pom.xml
@@ -37,7 +37,7 @@
org.dhis2.fhir.adapter
dhis2-fhir-adapter
- 0.1.0-SNAPSHOT
+ 1.0.0-SNAPSHOT
..
diff --git a/app/src/main/java/org/dhis2/fhir/adapter/App.java b/app/src/main/java/org/dhis2/fhir/adapter/App.java
index 610ebac1..1a0ebde6 100644
--- a/app/src/main/java/org/dhis2/fhir/adapter/App.java
+++ b/app/src/main/java/org/dhis2/fhir/adapter/App.java
@@ -28,6 +28,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+import org.apache.commons.lang3.StringUtils;
import org.dhis2.fhir.adapter.spring.YamlPropertySourceFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@@ -39,6 +40,8 @@
import org.springframework.context.annotation.PropertySource;
import org.springframework.jms.annotation.EnableJms;
+import java.io.File;
+
/**
* Main application entry point.
*
@@ -51,14 +54,50 @@
@PropertySource( value = { "classpath:default-application.yml", "file:///${dhis2.home}/services/fhir-adapter/application.yml" }, factory = YamlPropertySourceFactory.class )
public class App extends SpringBootServletInitializer
{
+ public static final String DHIS2_HOME_ENV = "DHIS2_HOME";
+
+ public static final String DHIS2_HOME_PROP = "dhis2.home";
+
@Override
protected SpringApplicationBuilder configure( SpringApplicationBuilder application )
{
+ checkEnv();
return application.sources( App.class );
}
public static void main( String[] args )
{
+ try
+ {
+ checkEnv();
+ }
+ catch ( AppException e )
+ {
+ System.err.println( e.getMessage() );
+ System.exit( 10 );
+ }
+
SpringApplication.run( App.class, args );
}
+
+ protected static void checkEnv() throws AppException
+ {
+ String home = System.getenv( DHIS2_HOME_ENV );
+ final String alternativeHome = System.getProperty( DHIS2_HOME_PROP );
+ if ( alternativeHome != null )
+ {
+ home = alternativeHome;
+ }
+
+ if ( StringUtils.isBlank( home ) )
+ {
+ throw new AppException( "DHIS2 home environment variable " + DHIS2_HOME_ENV + " has not been set." );
+ }
+
+ final File configFile = new File( home + "/services/fhir-adapter/application.yml" );
+ if ( !configFile.canRead() )
+ {
+ throw new AppException( "Adapter configuration file does not exist or cannot be read: " + configFile.getAbsolutePath() );
+ }
+ }
}
diff --git a/app/src/main/java/org/dhis2/fhir/adapter/AppException.java b/app/src/main/java/org/dhis2/fhir/adapter/AppException.java
new file mode 100644
index 00000000..b6d4259d
--- /dev/null
+++ b/app/src/main/java/org/dhis2/fhir/adapter/AppException.java
@@ -0,0 +1,44 @@
+package org.dhis2.fhir.adapter;
+
+/*
+ * Copyright (c) 2004-2018, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * Neither the name of the HISP project nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Thrown if the application cannot be started because of an environment problem.
+ *
+ * @author volsch
+ */
+public class AppException extends RuntimeException
+{
+ private static final long serialVersionUID = 8600075604012344988L;
+
+ public AppException( String message )
+ {
+ super( message );
+ }
+}
diff --git a/app/src/main/java/org/dhis2/fhir/adapter/DemoClient.java b/app/src/main/java/org/dhis2/fhir/adapter/DemoClient.java
index 783817ad..14671a8b 100644
--- a/app/src/main/java/org/dhis2/fhir/adapter/DemoClient.java
+++ b/app/src/main/java/org/dhis2/fhir/adapter/DemoClient.java
@@ -33,18 +33,26 @@
import ca.uhn.fhir.rest.client.api.IGenericClient;
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
import org.hl7.fhir.dstu3.model.Bundle;
+import org.hl7.fhir.dstu3.model.CodeableConcept;
import org.hl7.fhir.dstu3.model.Coding;
import org.hl7.fhir.dstu3.model.ContactPoint;
+import org.hl7.fhir.dstu3.model.DateTimeType;
import org.hl7.fhir.dstu3.model.DecimalType;
import org.hl7.fhir.dstu3.model.Enumerations;
import org.hl7.fhir.dstu3.model.Extension;
import org.hl7.fhir.dstu3.model.IdType;
+import org.hl7.fhir.dstu3.model.Immunization;
import org.hl7.fhir.dstu3.model.Location;
+import org.hl7.fhir.dstu3.model.Observation;
import org.hl7.fhir.dstu3.model.Organization;
import org.hl7.fhir.dstu3.model.Patient;
+import org.hl7.fhir.dstu3.model.Quantity;
import org.hl7.fhir.dstu3.model.Reference;
import org.hl7.fhir.dstu3.model.RelatedPerson;
+import org.hl7.fhir.dstu3.model.StringType;
+import org.hl7.fhir.dstu3.model.codesystems.ObservationCategory;
+import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Collections;
@@ -71,217 +79,460 @@ public static void main( String[] args )
System.err.println( "Syntax: ORG_CODE MOTHER_NATIONAL_ID CHILD_NATIONAL_ID" );
System.exit( 10 );
}
- int x = 61000;
- for ( int i = 0; i < 1000; i++ )
- {
- final String orgCode = args[0];
- final String motherNationalId = String.valueOf( x++ );
- final String childNationalId = String.valueOf( x++ );
-
- final FhirContext ctx = FhirContext.forDstu3();
- ctx.getRestfulClientFactory().setConnectTimeout( 20_000 );
- ctx.getRestfulClientFactory().setSocketTimeout( 40_000 );
- final IGenericClient client = ctx.newRestfulGenericClient( SERVER_BASE );
- client.registerInterceptor( new LoggingInterceptor( true ) );
-
- ///////////
- // Location
- ///////////
-
- Location location = new Location();
- location.setId( IdType.newRandomUuid() );
- location.setName( "Connaught Hospital" );
- location.addIdentifier()
- .setSystem( "http://example.sl/locations" )
- .setValue( orgCode );
- location.getAddress().setCity( "Freetown" );
- location.getPosition().setLatitude( 8.488431 ).setLongitude( -13.238409 );
-
- ///////////////
- // Organization
- ///////////////
-
- Organization hospitalOrg = new Organization();
- hospitalOrg.setId( IdType.newRandomUuid() );
- hospitalOrg.setName( "Connaught Hospital" );
- hospitalOrg.addIdentifier()
- .setSystem( "http://example.sl/organizations" )
- .setValue( orgCode );
-
- Organization org = new Organization();
- org.setId( IdType.newRandomUuid() );
- org.setName( "Registration Unit" );
- org.addIdentifier()
- .setSystem( "http://example.sl/organizations" )
- .setValue( "XZY123456" );
- org.setPartOf( new Reference( hospitalOrg.getIdElement() ) );
-
- Organization birthOrg = new Organization();
- birthOrg.setName( "Birth Unit" );
- birthOrg.setPartOf( new Reference( hospitalOrg.getIdElement() ) );
-
- //////////////////////////////////
- // Create Patient (new born child)
- //////////////////////////////////
-
- final LocalDate childBirthDate = LocalDate.now().minusDays( 8 );
-
- Patient child = new Patient();
- child.setIdElement( IdType.newRandomUuid() );
- child.addIdentifier()
- .setSystem( "http://example.sl/patients" )
- .setValue( childNationalId );
- child.addName()
- .setFamily( "West" )
- .addGiven( "Joe" ).addGiven( "Alan" ).addGiven( "Scott" );
- child.getBirthDateElement().setValue(
- Date.from( childBirthDate.atStartOfDay( ZoneId.systemDefault() ).toInstant() ),
- TemporalPrecisionEnum.DAY );
- child.setGender( Enumerations.AdministrativeGender.MALE );
- child.addAddress()
- .addLine( "Water Road 675" )
- .addLine( "Apartment 62" )
- .setCity( "Freetown" )
- .setCountry( "Sierra Leone" );
- child.getAddress().get( 0 )
- .addExtension()
- .setUrl( "http://hl7.org/fhir/StructureDefinition/geolocation" )
- .addExtension( new Extension()
- .setUrl( "latitude" )
- .setValue( new DecimalType( 8.4665341 ) ) )
- .addExtension( new Extension()
- .setUrl( "longitude" )
- .setValue( new DecimalType( -13.262743 ) ) );
- child.setManagingOrganization( new Reference( org.getId() ) );
-
- //////////////////////////
- // Create Patient (mother)
- //////////////////////////
-
- Patient mother = new Patient();
- mother.setIdElement( IdType.newRandomUuid() );
- mother.addIdentifier()
- .setSystem( "http://example.sl/patients" )
- .setValue( motherNationalId );
- mother.addName()
- .setFamily( "West" )
- .addGiven( "Elizabeth" );
- mother.getBirthDateElement().setValue(
- Date.from( LocalDate.now().minusYears( 16 ).atStartOfDay( ZoneId.systemDefault() ).toInstant() ),
- TemporalPrecisionEnum.DAY );
- mother.setGender( Enumerations.AdministrativeGender.FEMALE );
- mother.addAddress()
- .setCity( "Freetown" )
- .setCountry( "Sierra Leone" );
- mother.getAddress().get( 0 )
- .addExtension()
- .setUrl( "http://hl7.org/fhir/StructureDefinition/geolocation" )
- .addExtension( new Extension()
- .setUrl( "latitude" )
- .setValue( new DecimalType( 8.4665341 ) ) )
- .addExtension( new Extension()
- .setUrl( "longitude" )
- .setValue( new DecimalType( -13.262743 ) ) );
- mother.setManagingOrganization( new Reference( birthOrg ) );
-
- ////////////////////////////////////////
- // Transaction Bundle with Create/Update
- ////////////////////////////////////////
-
- Bundle bundle = new Bundle();
- bundle.setType( Bundle.BundleType.TRANSACTION );
- bundle.addEntry()
- .setResource( child )
- .setFullUrl( child.getId() )
- .getRequest()
- .setMethod( Bundle.HTTPVerb.PUT )
- .setUrl( "Patient?identifier=http://example.sl/patients|" + childNationalId );
- bundle.addEntry()
- .setResource( mother )
- .setFullUrl( mother.getId() )
- .getRequest()
- .setMethod( Bundle.HTTPVerb.PUT )
- .setUrl( "Patient?identifier=http://example.sl/patients|" + motherNationalId );
- bundle.addEntry()
- .setResource( location )
- .setFullUrl( location.getId() )
- .getRequest()
- .setMethod( Bundle.HTTPVerb.PUT )
- .setUrl( "Location?identifier=http://example.sl/locations|" + orgCode );
- bundle.addEntry()
- .setResource( hospitalOrg )
- .setFullUrl( hospitalOrg.getId() )
- .getRequest()
- .setMethod( Bundle.HTTPVerb.PUT )
- .setUrl( "Organization?identifier=http://example.sl/organizations|XZY123456" );
- bundle.addEntry()
- .setResource( org )
- .setFullUrl( org.getId() )
- .getRequest()
- .setMethod( Bundle.HTTPVerb.PUT )
- .setUrl( "Organization?identifier=http://example.sl/organizations|" + orgCode );
- client.transaction().withBundle( bundle ).execute();
-
- Bundle searchResult = client.search().forResource( Patient.class ).returnBundle( Bundle.class )
- .whereMap( Collections.singletonMap( "identifier", Collections.singletonList( "http://example.sl/patients|" + childNationalId ) ) ).execute();
- child = (Patient) searchResult.getEntry().get( 0 ).getResource();
- searchResult = client.search().forResource( Patient.class ).returnBundle( Bundle.class )
- .whereMap( Collections.singletonMap( "identifier", Collections.singletonList( "http://example.sl/patients|" + motherNationalId ) ) ).execute();
- mother = (Patient) searchResult.getEntry().get( 0 ).getResource();
-
- RelatedPerson childRelatedPerson = new RelatedPerson();
- childRelatedPerson.setActive( true );
- childRelatedPerson.getRelationship().addCoding(
- new Coding().setSystem( "http://hl7.org/fhir/v3/RoleCode" ).setCode( "MTH" ) );
- childRelatedPerson.setGender( Enumerations.AdministrativeGender.FEMALE );
- childRelatedPerson.addName().setFamily( "West" ).addGiven( "Elizabeth" );
- childRelatedPerson.addTelecom().setSystem( ContactPoint.ContactPointSystem.PHONE ).setValue( "(123) 456-7890.10" ).setRank( 1 ).setUse( ContactPoint.ContactPointUse.OLD );
- childRelatedPerson.addTelecom().setSystem( ContactPoint.ContactPointSystem.PHONE ).setValue( "(723) 456-7890.10" ).setRank( 2 ).setUse( ContactPoint.ContactPointUse.HOME );
- childRelatedPerson.getPatient().setReferenceElement( child.getIdElement().toUnqualifiedVersionless() );
- child.addLink().setType( Patient.LinkType.SEEALSO ).getOther().setResource( childRelatedPerson );
-
- RelatedPerson motherRelatedPerson = new RelatedPerson();
- motherRelatedPerson.setId( IdType.newRandomUuid() );
- motherRelatedPerson.addIdentifier().setSystem( "http://example.sl/relatedPersons" ).setValue( "mth" + motherNationalId );
- motherRelatedPerson.setActive( true );
- motherRelatedPerson.getRelationship().addCoding(
- new Coding().setSystem( "http://hl7.org/fhir/v3/RoleCode" ).setCode( "MTH" ) );
- motherRelatedPerson.setGender( Enumerations.AdministrativeGender.FEMALE );
- motherRelatedPerson.addName().setFamily( "West" ).addGiven( "Maria" );
- motherRelatedPerson.addTelecom().setSystem( ContactPoint.ContactPointSystem.PHONE ).setValue( "(723) 456-7890.20" ).setRank( 2 ).setUse( ContactPoint.ContactPointUse.HOME );
- motherRelatedPerson.getPatient().setReferenceElement( mother.getIdElement().toUnqualifiedVersionless() );
-
- bundle = new Bundle();
- bundle.setType( Bundle.BundleType.TRANSACTION );
- bundle.addEntry()
- .setResource( motherRelatedPerson )
- .setFullUrl( motherRelatedPerson.getId() )
- .getRequest()
- .setMethod( Bundle.HTTPVerb.PUT )
- .setUrl( "Patient?identifier=http://example.sl/relatedPersons|mth" + motherNationalId );
- bundle.addEntry()
- .setResource( child )
- .setFullUrl( child.getId() )
- .getRequest()
- .setMethod( Bundle.HTTPVerb.PUT )
- .setUrl( "Patient?identifier=http://example.sl/patients|" + childNationalId );
- client.transaction().withBundle( bundle ).execute();
-
- searchResult = client.search().forResource( RelatedPerson.class ).returnBundle( Bundle.class )
- .whereMap( Collections.singletonMap( "identifier", Collections.singletonList( "http://example.sl/relatedPersons|mth" + motherNationalId ) ) ).execute();
- motherRelatedPerson = (RelatedPerson) searchResult.getEntry().get( 0 ).getResource();
-
- mother.addLink().setType( Patient.LinkType.SEEALSO ).getOther().setReferenceElement( motherRelatedPerson.getIdElement().toUnqualifiedVersionless() );
-
- bundle = new Bundle();
- bundle.setType( Bundle.BundleType.TRANSACTION );
- bundle.addEntry()
- .setResource( mother )
- .setFullUrl( mother.getId() )
- .getRequest()
- .setMethod( Bundle.HTTPVerb.PUT )
- .setUrl( "Patient?identifier=http://example.sl/patients|" + motherNationalId );
- client.transaction().withBundle( bundle ).execute();
- }
+ final String orgCode = args[0];
+ final String motherNationalId = args[1];
+ final String childNationalId = args[2];
+
+ final FhirContext ctx = FhirContext.forDstu3();
+ final IGenericClient client = ctx.newRestfulGenericClient( SERVER_BASE );
+ client.registerInterceptor( new LoggingInterceptor( true ) );
+
+ ///////////
+ // Location
+ ///////////
+
+ Location location = new Location();
+ location.setId( IdType.newRandomUuid() );
+ location.setName( "Connaught Hospital" );
+ location.addIdentifier()
+ .setSystem( "http://example.sl/locations" )
+ .setValue( orgCode );
+ location.getAddress().setCity( "Freetown" );
+ location.getPosition().setLatitude( 8.488431 ).setLongitude( -13.238409 );
+
+ ///////////////
+ // Organization
+ ///////////////
+
+ Organization hospitalOrg = new Organization();
+ hospitalOrg.setId( IdType.newRandomUuid() );
+ hospitalOrg.setName( "Connaught Hospital" );
+ hospitalOrg.addIdentifier()
+ .setSystem( "http://example.sl/organizations" )
+ .setValue( orgCode );
+
+ Organization org = new Organization();
+ org.setId( IdType.newRandomUuid() );
+ org.setName( "Registration Unit" );
+ org.addIdentifier()
+ .setSystem( "http://example.sl/organizations" )
+ .setValue( "XZY123456" );
+ org.setPartOf( new Reference( hospitalOrg.getIdElement() ) );
+
+ Organization birthOrg = new Organization();
+ birthOrg.setName( "Birth Unit" );
+ birthOrg.setPartOf( new Reference( hospitalOrg.getIdElement() ) );
+
+ //////////////////////////////////
+ // Create Patient (new born child)
+ //////////////////////////////////
+
+ final LocalDate childBirthDate = LocalDate.now().minusDays( 8 );
+
+ Patient child = new Patient();
+ child.setIdElement( IdType.newRandomUuid() );
+ child.addIdentifier()
+ .setSystem( "http://example.sl/patients" )
+ .setValue( childNationalId );
+ child.addName()
+ .setFamily( "West" )
+ .addGiven( "Joe" ).addGiven( "Alan" ).addGiven( "Scott" );
+ child.getBirthDateElement().setValue(
+ Date.from( childBirthDate.atStartOfDay( ZoneId.systemDefault() ).toInstant() ),
+ TemporalPrecisionEnum.DAY );
+ child.setGender( Enumerations.AdministrativeGender.MALE );
+ child.addAddress()
+ .addLine( "Water Road 675" )
+ .addLine( "Apartment 62" )
+ .setCity( "Freetown" )
+ .setCountry( "Sierra Leone" );
+ child.getAddress().get( 0 )
+ .addExtension()
+ .setUrl( "http://hl7.org/fhir/StructureDefinition/geolocation" )
+ .addExtension( new Extension()
+ .setUrl( "latitude" )
+ .setValue( new DecimalType( 8.4665341 ) ) )
+ .addExtension( new Extension()
+ .setUrl( "longitude" )
+ .setValue( new DecimalType( -13.262743 ) ) );
+ child.setManagingOrganization( new Reference( org.getId() ) );
+
+ //////////////////////////
+ // Create Patient (mother)
+ //////////////////////////
+
+ Patient mother = new Patient();
+ mother.setIdElement( IdType.newRandomUuid() );
+ mother.addIdentifier()
+ .setSystem( "http://example.sl/patients" )
+ .setValue( motherNationalId );
+ mother.addName()
+ .setFamily( "West" )
+ .addGiven( "Elizabeth" );
+ mother.getBirthDateElement().setValue(
+ Date.from( LocalDate.now().minusYears( 16 ).atStartOfDay( ZoneId.systemDefault() ).toInstant() ),
+ TemporalPrecisionEnum.DAY );
+ mother.setGender( Enumerations.AdministrativeGender.FEMALE );
+ mother.addAddress()
+ .setCity( "Freetown" )
+ .setCountry( "Sierra Leone" );
+ mother.getAddress().get( 0 )
+ .addExtension()
+ .setUrl( "http://hl7.org/fhir/StructureDefinition/geolocation" )
+ .addExtension( new Extension()
+ .setUrl( "latitude" )
+ .setValue( new DecimalType( 8.4665341 ) ) )
+ .addExtension( new Extension()
+ .setUrl( "longitude" )
+ .setValue( new DecimalType( -13.262743 ) ) );
+ mother.setManagingOrganization( new Reference( birthOrg ) );
+
+ //////////////////////
+ // Create Vaccinations
+ //////////////////////
+
+ Immunization imm1 = new Immunization();
+ imm1.setId( IdType.newRandomUuid() );
+ imm1.getPatient().setReference( child.getId() );
+ imm1.getLocation().setReference( location.getId() );
+ imm1.setStatus( Immunization.ImmunizationStatus.COMPLETED );
+ imm1.getDateElement().setValue( new Date(), TemporalPrecisionEnum.SECOND );
+ imm1.setNotGiven( false );
+ imm1.setPrimarySource( true );
+ imm1.getVaccineCode()
+ .addCoding()
+ .setSystem( "http://hl7.org/fhir/sid/cvx" )
+ .setCode( "01" )
+ .setDisplay( "DTP" );
+ imm1.addVaccinationProtocol().setDoseSequence( 2 )
+ .setSeries( "2" );
+
+ Immunization imm2 = new Immunization();
+ imm2.setId( IdType.newRandomUuid() );
+ imm2.getPatient().setReference( child.getId() );
+ imm2.getLocation().setReference( location.getId() );
+ imm2.setStatus( Immunization.ImmunizationStatus.COMPLETED );
+ imm2.getDateElement().setValue( new Date(), TemporalPrecisionEnum.SECOND );
+ imm2.setNotGiven( false );
+ imm2.setPrimarySource( true );
+ imm2.getVaccineCode()
+ .addCoding()
+ .setSystem( "http://hl7.org/fhir/sid/cvx" )
+ .setCode( "03" )
+ .setDisplay( "MMR" );
+ imm2.addVaccinationProtocol().setDoseSequence( 2 )
+ .setSeries( "2" );
+
+ Immunization imm3 = new Immunization();
+ imm3.setId( IdType.newRandomUuid() );
+ imm3.getPatient().setReference( child.getId() );
+ imm3.getLocation().setReference( location.getId() );
+ imm3.setStatus( Immunization.ImmunizationStatus.COMPLETED );
+ imm3.getDateElement().setValue( new Date(), TemporalPrecisionEnum.SECOND );
+ imm3.setNotGiven( false );
+ imm3.setPrimarySource( true );
+ imm3.getVaccineCode()
+ .addCoding()
+ .setSystem( "http://hl7.org/fhir/sid/cvx" )
+ .setCode( "19" )
+ .setDisplay( "BCG" );
+ imm3.addVaccinationProtocol().setDoseSequence( 2 )
+ .setSeries( "2" );
+
+ Immunization imm4 = new Immunization();
+ imm4.setId( IdType.newRandomUuid() );
+ imm4.getPatient().setReference( child.getId() );
+ imm4.getLocation().setReference( location.getId() );
+ imm4.setStatus( Immunization.ImmunizationStatus.COMPLETED );
+ imm4.getDateElement().setValue( new Date(), TemporalPrecisionEnum.SECOND );
+ imm4.setNotGiven( false );
+ imm4.setPrimarySource( true );
+ imm4.getVaccineCode()
+ .addCoding()
+ .setSystem( "http://hl7.org/fhir/sid/cvx" )
+ .setCode( "02" )
+ .setDisplay( "OPV" );
+ imm4.addVaccinationProtocol().setDoseSequence( 2 )
+ .setSeries( "2" );
+
+ Immunization imm5 = new Immunization();
+ imm5.setId( IdType.newRandomUuid() );
+ imm5.getPatient().setReference( child.getId() );
+ imm5.getLocation().setReference( location.getId() );
+ imm5.setStatus( Immunization.ImmunizationStatus.COMPLETED );
+ imm5.getDateElement().setValue( new Date(), TemporalPrecisionEnum.SECOND );
+ imm5.setNotGiven( false );
+ imm5.setPrimarySource( true );
+ imm5.getVaccineCode()
+ .addCoding()
+ .setSystem( "http://hl7.org/fhir/sid/cvx" )
+ .setCode( "37" )
+ .setDisplay( "Yellow Fever" );
+ imm5.addVaccinationProtocol().setDoseSequence( 2 )
+ .setSeries( "2" );
+
+ //////////////
+ // Body Weight
+ //////////////
+
+ Observation bw1 = new Observation();
+ bw1.setId( IdType.newRandomUuid() );
+ bw1.addCategory( new CodeableConcept().addCoding(
+ new Coding().setSystem( ObservationCategory.VITALSIGNS.getSystem() ).setCode( ObservationCategory.VITALSIGNS.toCode() ) ) );
+ bw1.setCode( new CodeableConcept().addCoding( new Coding().setSystem( "http://loinc.org" ).setCode( "8339-4" ) ) );
+ bw1.getSubject().setReference( child.getId() );
+ bw1.setEffective( new DateTimeType( Date.from( childBirthDate.atStartOfDay( ZoneId.systemDefault() ).toInstant() ),
+ TemporalPrecisionEnum.DAY ) );
+ bw1.setValue( new Quantity().setValue( 119 ).setSystem( "http://unitsofmeasure.org" ).setCode( "[oz_av]" ) );
+
+ Observation bw2 = new Observation();
+ bw2.setId( IdType.newRandomUuid() );
+ bw2.addCategory( new CodeableConcept().addCoding(
+ new Coding().setSystem( ObservationCategory.VITALSIGNS.getSystem() ).setCode( ObservationCategory.VITALSIGNS.toCode() ) ) );
+ bw2.setCode( new CodeableConcept().addCoding( new Coding().setSystem( "http://loinc.org" ).setCode( "29463-7" ) ) );
+ bw2.getSubject().setReference( child.getId() );
+ bw2.setEffective( new DateTimeType( Date.from( childBirthDate.plusDays( 1 ).atStartOfDay( ZoneId.systemDefault() ).toInstant() ),
+ TemporalPrecisionEnum.DAY ) );
+ bw2.setValue( new Quantity().setValue( 20 ).setSystem( "http://unitsofmeasure.org" ).setCode( "kg" ) );
+
+ Observation bw3 = new Observation();
+ bw3.setId( IdType.newRandomUuid() );
+ bw3.addCategory( new CodeableConcept().addCoding(
+ new Coding().setSystem( ObservationCategory.VITALSIGNS.getSystem() ).setCode( ObservationCategory.VITALSIGNS.toCode() ) ) );
+ bw3.setCode( new CodeableConcept().addCoding( new Coding().setSystem( "http://loinc.org" ).setCode( "29463-7" ) ) );
+ bw3.getSubject().setReference( child.getId() );
+ bw3.setEffective( new DateTimeType( Date.from( childBirthDate.plusDays( BABY_POSTNATAL_STAGE_DAYS ).atStartOfDay( ZoneId.systemDefault() ).toInstant() ),
+ TemporalPrecisionEnum.DAY ) );
+ bw3.setValue( new Quantity().setValue( 3100 ).setSystem( "http://unitsofmeasure.org" ).setCode( "g" ) );
+
+ //////////////
+ // Apgar Score
+ //////////////
+
+ Observation as10 = new Observation();
+ as10.setId( IdType.newRandomUuid() );
+ as10.addCategory( new CodeableConcept().addCoding(
+ new Coding().setSystem( ObservationCategory.SURVEY.getSystem() ).setCode( ObservationCategory.SURVEY.toCode() ) ) );
+ as10.setCode( new CodeableConcept().addCoding( new Coding().setSystem( "http://loinc.org" ).setCode( "9273-4" ) ) );
+ as10.getSubject().setReference( child.getId() );
+ as10.setEffective( new DateTimeType( Date.from( childBirthDate.atStartOfDay( ZoneId.systemDefault() ).toInstant() ),
+ TemporalPrecisionEnum.DAY ) );
+ as10.addComponent().setCode( new CodeableConcept().addCoding(
+ new Coding().setSystem( "http://loinc.org/la" ).setCode( "LA6724-4" ).setDisplay( "Good color all over" ) ) )
+ .setValue( new StringType( "2. Good color all over" ) );
+ as10.addComponent().setCode( new CodeableConcept().addCoding(
+ new Coding().setSystem( "http://loinc.org/la" ).setCode( "LA6718-6" ).setDisplay( "At least 100 beats per minute" ) ) )
+ .setValue( new StringType( "2. At least 100 beats per minute" ) );
+ as10.setValue( new Quantity().setValue( 10 ).setCode( "{score}" ) );
+
+ Observation as2 = new Observation();
+ as2.setId( IdType.newRandomUuid() );
+ as2.addCategory( new CodeableConcept().addCoding(
+ new Coding().setSystem( ObservationCategory.SURVEY.getSystem() ).setCode( ObservationCategory.SURVEY.toCode() ) ) );
+ as2.setCode( new CodeableConcept().addCoding( new Coding().setSystem( "http://loinc.org" ).setCode( "9271-8" ) ) );
+ as2.getSubject().setReference( child.getId() );
+ as2.setEffective( new DateTimeType( Date.from( childBirthDate.atStartOfDay( ZoneId.systemDefault() ).toInstant() ),
+ TemporalPrecisionEnum.DAY ) );
+ as2.setValue( new Quantity().setValue( 4 ).setCode( "{score}" ) );
+
+ ////////////////////////
+ // Last Menstrual Period
+ ////////////////////////
+
+ Observation lmp = new Observation();
+ lmp.setId( IdType.newRandomUuid() );
+ lmp.addCategory( new CodeableConcept().addCoding(
+ new Coding().setSystem( ObservationCategory.SOCIALHISTORY.getSystem() ).setCode( ObservationCategory.SOCIALHISTORY.toCode() ) ) );
+ lmp.setCode( new CodeableConcept().addCoding( new Coding().setSystem( "http://loinc.org" ).setCode( "8665-2" ) ) );
+ lmp.getSubject().setReference( mother.getId() );
+ lmp.setValue( new DateTimeType(
+ Date.from( LocalDate.now().minusDays( 7 ).atStartOfDay( ZoneId.systemDefault() ).toInstant() ), TemporalPrecisionEnum.DAY ) );
+
+ /////////////////
+ // Blood Pressure
+ /////////////////
+
+ Observation bloodPressure = new Observation();
+ bloodPressure.setId( IdType.newRandomUuid() );
+ bloodPressure.setStatus( Observation.ObservationStatus.FINAL );
+ bloodPressure.addCategory( new CodeableConcept().addCoding(
+ new Coding().setSystem( ObservationCategory.VITALSIGNS.getSystem() ).setCode( ObservationCategory.VITALSIGNS.toCode() ) ) );
+ bloodPressure.setCode( new CodeableConcept().addCoding( new Coding().setSystem( "http://loinc.org" ).setCode( "85354-9" ) ) );
+ bloodPressure.getSubject().setReference( mother.getId() );
+ bloodPressure.addComponent().setCode( new CodeableConcept().addCoding( new Coding().setSystem( "http://loinc.org" ).setCode( "8480-6" ) ) )
+ .setValue( new Quantity().setValue( new BigDecimal( 120L ) ).setCode( "UCUM" ).setUnit( "mm[Hg]" ) );
+ bloodPressure.addComponent().setCode( new CodeableConcept().addCoding( new Coding().setSystem( "http://loinc.org" ).setCode( "8462-4" ) ) )
+ .setValue( new Quantity().setValue( new BigDecimal( 100L ) ).setCode( "UCUM" ).setUnit( "mm[Hg]" ) );
+
+ ////////////////////////////////////////
+ // Transaction Bundle with Create/Update
+ ////////////////////////////////////////
+
+ Bundle bundle = new Bundle();
+ bundle.setType( Bundle.BundleType.TRANSACTION );
+ bundle.addEntry()
+ .setResource( child )
+ .setFullUrl( child.getId() )
+ .getRequest()
+ .setMethod( Bundle.HTTPVerb.PUT )
+ .setUrl( "Patient?identifier=http://example.sl/patients|" + childNationalId );
+ bundle.addEntry()
+ .setResource( mother )
+ .setFullUrl( mother.getId() )
+ .getRequest()
+ .setMethod( Bundle.HTTPVerb.PUT )
+ .setUrl( "Patient?identifier=http://example.sl/patients|" + motherNationalId );
+ bundle.addEntry()
+ .setResource( location )
+ .setFullUrl( location.getId() )
+ .getRequest()
+ .setMethod( Bundle.HTTPVerb.PUT )
+ .setUrl( "Location?identifier=http://example.sl/locations|" + orgCode );
+ bundle.addEntry()
+ .setResource( hospitalOrg )
+ .setFullUrl( hospitalOrg.getId() )
+ .getRequest()
+ .setMethod( Bundle.HTTPVerb.PUT )
+ .setUrl( "Organization?identifier=http://example.sl/organizations|XZY123456" );
+ bundle.addEntry()
+ .setResource( org )
+ .setFullUrl( org.getId() )
+ .getRequest()
+ .setMethod( Bundle.HTTPVerb.PUT )
+ .setUrl( "Organization?identifier=http://example.sl/organizations|" + orgCode );
+ bundle.addEntry()
+ .setResource( imm1 )
+ .setFullUrl( imm1.getId() )
+ .getRequest()
+ .setMethod( Bundle.HTTPVerb.POST )
+ .setUrl( "Immunization" );
+ bundle.addEntry()
+ .setResource( imm2 )
+ .setFullUrl( imm2.getId() )
+ .getRequest()
+ .setMethod( Bundle.HTTPVerb.POST )
+ .setUrl( "Immunization" );
+ bundle.addEntry()
+ .setResource( imm3 )
+ .setFullUrl( imm3.getId() )
+ .getRequest()
+ .setMethod( Bundle.HTTPVerb.POST )
+ .setUrl( "Immunization" );
+ bundle.addEntry()
+ .setResource( imm4 )
+ .setFullUrl( imm4.getId() )
+ .getRequest()
+ .setMethod( Bundle.HTTPVerb.POST )
+ .setUrl( "Immunization" );
+ bundle.addEntry()
+ .setResource( imm5 )
+ .setFullUrl( imm5.getId() )
+ .getRequest()
+ .setMethod( Bundle.HTTPVerb.POST )
+ .setUrl( "Immunization" );
+ bundle.addEntry()
+ .setResource( bw1 )
+ .setFullUrl( bw1.getId() )
+ .getRequest()
+ .setMethod( Bundle.HTTPVerb.POST )
+ .setUrl( "Observation" );
+ bundle.addEntry()
+ .setResource( bw2 )
+ .setFullUrl( bw2.getId() )
+ .getRequest()
+ .setMethod( Bundle.HTTPVerb.POST )
+ .setUrl( "Observation" );
+ bundle.addEntry()
+ .setResource( bw3 )
+ .setFullUrl( bw3.getId() )
+ .getRequest()
+ .setMethod( Bundle.HTTPVerb.POST )
+ .setUrl( "Observation" );
+ bundle.addEntry()
+ .setResource( as10 )
+ .setFullUrl( as10.getId() )
+ .getRequest()
+ .setMethod( Bundle.HTTPVerb.POST )
+ .setUrl( "Observation" );
+ bundle.addEntry()
+ .setResource( as2 )
+ .setFullUrl( as2.getId() )
+ .getRequest()
+ .setMethod( Bundle.HTTPVerb.POST )
+ .setUrl( "Observation" );
+ bundle.addEntry()
+ .setResource( lmp )
+ .setFullUrl( lmp.getId() )
+ .getRequest()
+ .setMethod( Bundle.HTTPVerb.POST )
+ .setUrl( "Observation" );
+ bundle.addEntry()
+ .setResource( bloodPressure )
+ .setFullUrl( bloodPressure.getId() )
+ .getRequest()
+ .setMethod( Bundle.HTTPVerb.POST )
+ .setUrl( "Observation" );
+ client.transaction().withBundle( bundle ).execute();
+
+ Bundle searchResult = client.search().forResource( Patient.class ).returnBundle( Bundle.class )
+ .whereMap( Collections.singletonMap( "identifier", Collections.singletonList( "http://example.sl/patients|" + childNationalId ) ) ).execute();
+ child = (Patient) searchResult.getEntry().get( 0 ).getResource();
+ searchResult = client.search().forResource( Patient.class ).returnBundle( Bundle.class )
+ .whereMap( Collections.singletonMap( "identifier", Collections.singletonList( "http://example.sl/patients|" + motherNationalId ) ) ).execute();
+ mother = (Patient) searchResult.getEntry().get( 0 ).getResource();
+
+ RelatedPerson childRelatedPerson = new RelatedPerson();
+ childRelatedPerson.setActive( true );
+ childRelatedPerson.getRelationship().addCoding(
+ new Coding().setSystem( "http://hl7.org/fhir/v3/RoleCode" ).setCode( "MTH" ) );
+ childRelatedPerson.setGender( Enumerations.AdministrativeGender.FEMALE );
+ childRelatedPerson.addName().setFamily( "West" ).addGiven( "Elizabeth" );
+ childRelatedPerson.addTelecom().setSystem( ContactPoint.ContactPointSystem.PHONE ).setValue( "(123) 456-7890.10" ).setRank( 1 ).setUse( ContactPoint.ContactPointUse.OLD );
+ childRelatedPerson.addTelecom().setSystem( ContactPoint.ContactPointSystem.PHONE ).setValue( "(723) 456-7890.10" ).setRank( 2 ).setUse( ContactPoint.ContactPointUse.HOME );
+ childRelatedPerson.getPatient().setReferenceElement( child.getIdElement().toUnqualifiedVersionless() );
+ child.addLink().setType( Patient.LinkType.SEEALSO ).getOther().setResource( childRelatedPerson );
+
+ RelatedPerson motherRelatedPerson = new RelatedPerson();
+ motherRelatedPerson.setId( IdType.newRandomUuid() );
+ motherRelatedPerson.addIdentifier().setSystem( "http://example.sl/relatedPersons" ).setValue( "mth" + motherNationalId );
+ motherRelatedPerson.setActive( true );
+ motherRelatedPerson.getRelationship().addCoding(
+ new Coding().setSystem( "http://hl7.org/fhir/v3/RoleCode" ).setCode( "MTH" ) );
+ motherRelatedPerson.setGender( Enumerations.AdministrativeGender.FEMALE );
+ motherRelatedPerson.addName().setFamily( "West" ).addGiven( "Maria" );
+ motherRelatedPerson.addTelecom().setSystem( ContactPoint.ContactPointSystem.PHONE ).setValue( "(723) 456-7890.20" ).setRank( 2 ).setUse( ContactPoint.ContactPointUse.HOME );
+ motherRelatedPerson.getPatient().setReferenceElement( mother.getIdElement().toUnqualifiedVersionless() );
+
+ bundle = new Bundle();
+ bundle.setType( Bundle.BundleType.TRANSACTION );
+ bundle.addEntry()
+ .setResource( motherRelatedPerson )
+ .setFullUrl( motherRelatedPerson.getId() )
+ .getRequest()
+ .setMethod( Bundle.HTTPVerb.PUT )
+ .setUrl( "Patient?identifier=http://example.sl/relatedPersons|mth" + motherNationalId );
+ bundle.addEntry()
+ .setResource( child )
+ .setFullUrl( child.getId() )
+ .getRequest()
+ .setMethod( Bundle.HTTPVerb.PUT )
+ .setUrl( "Patient?identifier=http://example.sl/patients|" + childNationalId );
+ client.transaction().withBundle( bundle ).execute();
+
+ searchResult = client.search().forResource( RelatedPerson.class ).returnBundle( Bundle.class )
+ .whereMap( Collections.singletonMap( "identifier", Collections.singletonList( "http://example.sl/relatedPersons|mth" + motherNationalId ) ) ).execute();
+ motherRelatedPerson = (RelatedPerson) searchResult.getEntry().get( 0 ).getResource();
+
+ mother.addLink().setType( Patient.LinkType.SEEALSO ).getOther().setReferenceElement( motherRelatedPerson.getIdElement().toUnqualifiedVersionless() );
+
+ bundle = new Bundle();
+ bundle.setType( Bundle.BundleType.TRANSACTION );
+ bundle.addEntry()
+ .setResource( mother )
+ .setFullUrl( mother.getId() )
+ .getRequest()
+ .setMethod( Bundle.HTTPVerb.PUT )
+ .setUrl( "Patient?identifier=http://example.sl/patients|" + motherNationalId );
+ client.transaction().withBundle( bundle ).execute();
}
}
diff --git a/app/src/main/java/org/dhis2/fhir/adapter/setup/RemoteSubscriptionFhirSetup.java b/app/src/main/java/org/dhis2/fhir/adapter/setup/RemoteSubscriptionFhirSetup.java
index 92f8051a..f49737fc 100644
--- a/app/src/main/java/org/dhis2/fhir/adapter/setup/RemoteSubscriptionFhirSetup.java
+++ b/app/src/main/java/org/dhis2/fhir/adapter/setup/RemoteSubscriptionFhirSetup.java
@@ -63,7 +63,7 @@ public class RemoteSubscriptionFhirSetup implements Serializable
private SubscriptionType subscriptionType = SubscriptionType.REST_HOOK_WITH_JSON_PAYLOAD;
@Min( value = 0, message = "Must be a positive value." )
- private int toleranceMillis = 5_000;
+ private int toleranceMillis = 2_000;
private boolean supportsRelatedPerson;
diff --git a/common/pom.xml b/common/pom.xml
index 20f2d15d..c6c3dfbd 100644
--- a/common/pom.xml
+++ b/common/pom.xml
@@ -37,7 +37,7 @@
org.dhis2.fhir.adapter
dhis2-fhir-adapter
- 0.1.0-SNAPSHOT
+ 1.0.0-SNAPSHOT
..
diff --git a/dhis/pom.xml b/dhis/pom.xml
index 96da9bb3..3bd5d78b 100644
--- a/dhis/pom.xml
+++ b/dhis/pom.xml
@@ -37,7 +37,7 @@
org.dhis2.fhir.adapter
dhis2-fhir-adapter
- 0.1.0-SNAPSHOT
+ 1.0.0-SNAPSHOT
..
diff --git a/fhir-dstu3/pom.xml b/fhir-dstu3/pom.xml
index 2aaced13..45f25ae6 100644
--- a/fhir-dstu3/pom.xml
+++ b/fhir-dstu3/pom.xml
@@ -37,7 +37,7 @@
org.dhis2.fhir.adapter
dhis2-fhir-adapter
- 0.1.0-SNAPSHOT
+ 1.0.0-SNAPSHOT
..
diff --git a/fhir/pom.xml b/fhir/pom.xml
index 192157ff..8ebcb222 100644
--- a/fhir/pom.xml
+++ b/fhir/pom.xml
@@ -37,7 +37,7 @@
org.dhis2.fhir.adapter
dhis2-fhir-adapter
- 0.1.0-SNAPSHOT
+ 1.0.0-SNAPSHOT
..
diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/remote/impl/AbstractSubscriptionResourceBundleRetriever.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/remote/impl/AbstractSubscriptionResourceBundleRetriever.java
index 93645bd5..3c699677 100644
--- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/remote/impl/AbstractSubscriptionResourceBundleRetriever.java
+++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/remote/impl/AbstractSubscriptionResourceBundleRetriever.java
@@ -52,7 +52,6 @@
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
-import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Collection;
@@ -80,8 +79,6 @@ public abstract class AbstractSubscriptionResourceBundleRetriever implements Fhi
private final FhirContext fhirContext;
- private final ZoneId zoneId = ZoneId.systemDefault();
-
protected AbstractSubscriptionResourceBundleRetriever( @Nonnull FhirContext fhirContext )
{
this.fhirContext = fhirContext;
@@ -111,7 +108,7 @@ public Instant poll( @Nonnull RemoteSubscriptionResource subscriptionResource, @
}
fromLastUpdated = fromLastUpdated
.minus( subscriptionResource.getRemoteSubscription().getToleranceMillis(), ChronoUnit.MILLIS );
- IBaseBundle bundle = createBaseQuery( client, resourceName, subscriptionResource, maxSearchCount, fromLastUpdated )
+ IBaseBundle bundle = createBaseQuery( client, resourceName, subscriptionResource, fromLastUpdated ).count( maxSearchCount )
.elementsSubset( "meta", "id" ).returnBundle( getBundleClass() ).sort().ascending( "_lastUpdated" ).execute();
do
{
@@ -130,15 +127,6 @@ public Instant poll( @Nonnull RemoteSubscriptionResource subscriptionResource, @
}
} );
- final Long totalCount = paging ? null : getTotalCount( client, resourceName, subscriptionResource, maxSearchCount, fromLastUpdated, bundle );
- if ( !paging && (previousResources != null) && !resources.isEmpty() && previousResources.containsAll( resources ) &&
- (previousResources.size() >= resources.size()) && (resources.size() < totalCount) )
- {
- throw new RemoteRestHookProcessorException( "Remote subscription resource " + subscriptionResource.getId() + " returned same result for last updated " +
- fromLastUpdated + " (count " + resources.size() + " of maximum " + maxSearchCount + ")." );
- }
- previousResources = new HashSet<>( resources );
-
moreAvailable = false;
if ( resources.isEmpty() )
{
@@ -150,6 +138,7 @@ public Instant poll( @Nonnull RemoteSubscriptionResource subscriptionResource, @
bundle = backwardPaging ? loadPreviousPage( client, currentBundle ) : loadNextPage( client, currentBundle );
if ( isEmpty( bundle ) )
{
+ long totalCount;
bundle = null;
if ( paging )
{
@@ -164,10 +153,25 @@ public Instant poll( @Nonnull RemoteSubscriptionResource subscriptionResource, @
}
}
}
- else if ( resources.size() < totalCount )
+ else if ( resources.size() < (totalCount = getTotalCount( client, resourceName, subscriptionResource, fromLastUpdated, currentBundle )) )
{
logger.debug( "Returned {} of {} for remote subscription resource {} with maximum requested {}.",
resources.size(), totalCount, subscriptionResource.getId(), maxSearchCount );
+ final Instant minLastUpdated = resources.stream().map( SubscriptionResourceInfo::getLastUpdated )
+ .filter( lu -> (lu != null) ).min( Comparator.naturalOrder() ).orElse( null );
+ if ( (minLastUpdated != null) && minLastUpdated.isBefore( fromLastUpdated ) )
+ {
+ logger.warn( "Remote subscription resource {} returned minimum last updated {} for lower bound {}.",
+ subscriptionResource.getId(), minLastUpdated, fromLastUpdated );
+ }
+
+ if ( (previousResources != null) && previousResources.containsAll( resources ) && (previousResources.size() >= resources.size()) )
+ {
+ throw new RemoteRestHookProcessorException( "Remote subscription resource " + subscriptionResource.getId() + " returned same result for last updated " +
+ fromLastUpdated + " (count " + resources.size() + " of maximum " + maxSearchCount + ")." );
+ }
+ previousResources = new HashSet<>( resources );
+
final Instant maxLastUpdated = resources.stream().map( SubscriptionResourceInfo::getLastUpdated )
.filter( lu -> (lu != null) ).max( Comparator.naturalOrder() ).orElse( null );
if ( maxLastUpdated == null )
@@ -176,15 +180,15 @@ else if ( resources.size() < totalCount )
}
else
{
- if ( maxLastUpdated.equals( fromLastUpdated ) )
+ if ( maxLastUpdated.isAfter( fromLastUpdated ) )
{
- throw new RemoteRestHookProcessorException( "Remote subscription resource " + subscriptionResource.getId() + " last updated timestamp " +
- fromLastUpdated + " has not been changed after processing " + resources.size() + " resources (total " + totalCount + ")." );
+ fromLastUpdated = maxLastUpdated;
+ moreAvailable = true;
}
else
{
- fromLastUpdated = maxLastUpdated;
- moreAvailable = true;
+ throw new RemoteRestHookProcessorException( "Remote subscription resource " + subscriptionResource.getId() + " last updated timestamp " +
+ fromLastUpdated + " has not been changed after processing " + resources.size() + " resources (total " + totalCount + ")." );
}
}
}
@@ -200,11 +204,14 @@ else if ( resources.size() < totalCount )
while ( moreAvailable );
// resources should not be consumed inside the loop above since paging may take longer
- consumer.accept( orderedAllResources );
+ if ( !orderedAllResources.isEmpty() )
+ {
+ consumer.accept( orderedAllResources );
+ }
return lastUpdated;
}
- protected long getTotalCount( @Nonnull IGenericClient client, @Nonnull String resourceName, @Nonnull RemoteSubscriptionResource subscriptionResource, int maxSearchCount, @Nonnull Instant fromLastUpdated, @Nonnull IBaseBundle bundle )
+ protected long getTotalCount( @Nonnull IGenericClient client, @Nonnull String resourceName, @Nonnull RemoteSubscriptionResource subscriptionResource, @Nonnull Instant fromLastUpdated, @Nonnull IBaseBundle bundle )
{
Long totalCount = getBundleTotalCount( bundle );
if ( totalCount != null )
@@ -212,8 +219,7 @@ protected long getTotalCount( @Nonnull IGenericClient client, @Nonnull String re
return totalCount;
}
- final IBaseBundle newBundle = client.search().forResource( resourceName ).cacheControl( new CacheControlDirective().setNoCache( true ) )
- .whereMap( getQuery( subscriptionResource ) ).count( maxSearchCount ).lastUpdated( new DateRangeParam( Date.from( fromLastUpdated ), null ) )
+ final IBaseBundle newBundle = createBaseQuery( client, resourceName, subscriptionResource, fromLastUpdated )
.summaryMode( SummaryEnum.COUNT ).returnBundle( getBundleClass() ).execute();
totalCount = getBundleTotalCount( newBundle );
if ( totalCount == null )
@@ -224,10 +230,11 @@ protected long getTotalCount( @Nonnull IGenericClient client, @Nonnull String re
}
@Nonnull
- protected IQuery extends IBaseBundle> createBaseQuery( @Nonnull IGenericClient client, @Nonnull String resourceName, @Nonnull RemoteSubscriptionResource subscriptionResource, int maxSearchCount, @Nonnull Instant fromLastUpdated )
+ protected IQuery extends IBaseBundle> createBaseQuery( @Nonnull IGenericClient client, @Nonnull String resourceName, @Nonnull RemoteSubscriptionResource subscriptionResource, @Nonnull Instant fromLastUpdated )
{
- return client.search().forResource( resourceName ).cacheControl( new CacheControlDirective().setNoCache( true ) )
- .whereMap( getQuery( subscriptionResource ) ).count( maxSearchCount ).lastUpdated( new DateRangeParam( Date.from( fromLastUpdated ), null ) );
+ return client.search().forResource( resourceName )
+ .whereMap( getQuery( subscriptionResource ) ).lastUpdated( new DateRangeParam( Date.from( fromLastUpdated ), null ) )
+ .cacheControl( new CacheControlDirective().setNoCache( true ) );
}
@Nonnull
@@ -256,7 +263,7 @@ protected Map> getQuery( @Nonnull RemoteSubscriptionResourc
}
final String parameters = subscriptionResource.getFhirCriteriaParameters().trim();
- final StringBuilder url = new StringBuilder( "test" );
+ final StringBuilder url = new StringBuilder();
if ( !parameters.startsWith( "?" ) )
{
url.append( "?" );
diff --git a/pom.xml b/pom.xml
index f265a6de..1b438531 100644
--- a/pom.xml
+++ b/pom.xml
@@ -33,7 +33,7 @@
org.dhis2.fhir.adapter
dhis2-fhir-adapter
- 0.1.0-SNAPSHOT
+ 1.0.0-SNAPSHOT
pom