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 createBaseQuery( @Nonnull IGenericClient client, @Nonnull String resourceName, @Nonnull RemoteSubscriptionResource subscriptionResource, int maxSearchCount, @Nonnull Instant fromLastUpdated ) + protected IQuery 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