From c6cc85f960adb33843bccddff1bfc9f08fd2707d Mon Sep 17 00:00:00 2001 From: Volker Schmidt Date: Mon, 29 Jul 2019 22:45:12 +0200 Subject: [PATCH] Provides polling support for plan definitions. --- .../AbstractProgramStageFhirRestAppTest.java | 5 +- .../r4/R4ProgramMetadataFhirRestAppTest.java | 17 ++--- ...stractEnrollmentTransformationAppTest.java | 7 +- ...ractProgramStageTransformationAppTest.java | 5 +- .../adapter/dhis/model/DhisResourceType.java | 28 ++++---- .../impl/OrganizationUnitServiceImpl.java | 2 +- .../dhis/service/DhisMetadataService.java | 12 +--- .../dhis/service/DhisPolledService.java | 52 +++++++++++++++ .../adapter/dhis/service/DhisService.java | 46 +++++++++++++ .../impl/AbstractDhisMetadataServiceImpl.java | 2 +- .../DhisDataProcessorItemRetrieverImpl.java | 66 ++++++------------- .../tracker/program/EnrollmentService.java | 4 +- .../dhis/tracker/program/EventService.java | 13 +--- .../dhis/tracker/program/WritableProgram.java | 4 +- .../program/impl/EnrollmentServiceImpl.java | 8 +++ .../program/impl/EventServiceImpl.java | 8 +++ .../impl/ProgramMetadataServiceImpl.java | 4 +- .../trackedentity/TrackedEntityService.java | 13 +--- .../impl/TrackedEntityServiceImpl.java | 7 ++ .../impl/ProgramMetadataServiceImplTest.java | 15 +++-- .../impl/AbstractDhisToFhirTransformer.java | 7 +- 21 files changed, 204 insertions(+), 121 deletions(-) create mode 100644 dhis/src/main/java/org/dhis2/fhir/adapter/dhis/service/DhisPolledService.java create mode 100644 dhis/src/main/java/org/dhis2/fhir/adapter/dhis/service/DhisService.java diff --git a/app/src/test/java/org/dhis2/fhir/adapter/fhir/server/AbstractProgramStageFhirRestAppTest.java b/app/src/test/java/org/dhis2/fhir/adapter/fhir/server/AbstractProgramStageFhirRestAppTest.java index 8962a7e8..b7ed5cd6 100644 --- a/app/src/test/java/org/dhis2/fhir/adapter/fhir/server/AbstractProgramStageFhirRestAppTest.java +++ b/app/src/test/java/org/dhis2/fhir/adapter/fhir/server/AbstractProgramStageFhirRestAppTest.java @@ -67,12 +67,13 @@ protected void expectProgramStageMetadataRequests() throws Exception .andRespond( withSuccess( IOUtils.resourceToString( "/org/dhis2/fhir/adapter/dhis/test/single-org-unit-OU_1234.json", StandardCharsets.UTF_8 ), MediaType.APPLICATION_JSON ) ); systemDhis2Server.expect( ExpectedCount.between( 0, 1 ), method( HttpMethod.GET ) ).andExpect( header( "Authorization", testConfiguration.getDhis2SystemAuthorization() ) ) .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/programs/EPDyQuoRnXk.json?" + - "fields=id,name,code,description,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration,withoutRegistration,captureCoordinates,trackedEntityType%5Bid%5D,programTrackedEntityAttributes%5Bid,name,valueType," + + "fields=id,name,code,description,lastUpdated,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration,withoutRegistration,captureCoordinates,trackedEntityType%5Bid%5D,programTrackedEntityAttributes%5Bid," + + "name,valueType," + "mandatory,allowFutureDate,trackedEntityAttribute%5Bid,name,code,valueType,generated%5D%5D,programStages%5Bid,name,description,repeatable,captureCoordinates,generatedByEnrollmentDate,minDaysFromStart,programStageDataElements%5Bid,compulsory," + "allowProvidedElsewhere,dataElement%5Bid,name,code,formName,valueType,optionSetValue,optionSet%5Bid,name,options%5Bcode,name%5D%5D%5D%5D%5D" ) ) .andRespond( withSuccess( IOUtils.resourceToString( "/org/dhis2/fhir/adapter/dhis/test/single-program.json", StandardCharsets.UTF_8 ), MediaType.APPLICATION_JSON ) ); systemDhis2Server.expect( ExpectedCount.between( 0, 1 ), method( HttpMethod.GET ) ).andExpect( header( "Authorization", testConfiguration.getDhis2SystemAuthorization() ) ) - .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/programs.json?paging=false&fields=id,name,code,description,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration," + + .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/programs.json?paging=false&fields=id,name,code,description,lastUpdated,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration," + "withoutRegistration,captureCoordinates,trackedEntityType%5Bid%5D,programTrackedEntityAttributes%5Bid,name,valueType,mandatory,allowFutureDate,trackedEntityAttribute%5Bid,name,code,valueType,generated%5D%5D,programStages%5Bid,name," + "description,repeatable,captureCoordinates,generatedByEnrollmentDate,minDaysFromStart,programStageDataElements%5Bid,compulsory,allowProvidedElsewhere,dataElement%5Bid,name,code,formName,valueType,optionSetValue,optionSet%5Bid,name," + "options%5Bcode,name%5D%5D%5D%5D%5D&filter=name:eq:Child%20Programme" ) ) diff --git a/app/src/test/java/org/dhis2/fhir/adapter/fhir/server/r4/R4ProgramMetadataFhirRestAppTest.java b/app/src/test/java/org/dhis2/fhir/adapter/fhir/server/r4/R4ProgramMetadataFhirRestAppTest.java index 1402d045..695d91d2 100644 --- a/app/src/test/java/org/dhis2/fhir/adapter/fhir/server/r4/R4ProgramMetadataFhirRestAppTest.java +++ b/app/src/test/java/org/dhis2/fhir/adapter/fhir/server/r4/R4ProgramMetadataFhirRestAppTest.java @@ -78,7 +78,8 @@ public void getPlanDefinitionWithInvalidAuthorization() { userDhis2Server.expect( ExpectedCount.once(), method( HttpMethod.GET ) ).andExpect( header( "Authorization", "Basic Zmhpcl9jbGllbnQ6aW52YWxpZF8x" ) ) .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/programs/EPDyQuoRnXk.json?" + - "fields=id,name,code,description,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration,withoutRegistration,captureCoordinates,trackedEntityType%5Bid%5D,programTrackedEntityAttributes%5Bid,name,valueType," + + "fields=id,name,code,description,lastUpdated,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration,withoutRegistration,captureCoordinates,trackedEntityType%5Bid%5D,programTrackedEntityAttributes%5Bid," + + "name,valueType," + "mandatory,allowFutureDate,trackedEntityAttribute%5Bid,name,code,valueType,generated%5D%5D,programStages%5Bid,name,description,repeatable,captureCoordinates,generatedByEnrollmentDate,minDaysFromStart,programStageDataElements%5Bid,compulsory," + "allowProvidedElsewhere,dataElement%5Bid,name,code,formName,valueType,optionSetValue,optionSet%5Bid,name,options%5Bcode,name%5D%5D%5D%5D%5D" ) ) .andRespond( withStatus( HttpStatus.UNAUTHORIZED ) ); @@ -105,13 +106,13 @@ private void getPlanDefinition() throws Exception "fields=id,name,trackedEntityTypeAttributes%5Bid,name,valueType,mandatory,trackedEntityAttribute%5Bid,name,code,valueType,generated,optionSetValue,optionSet%5Bid,name,options%5Bcode,name%5D%5D%5D%5D" ) ) .andRespond( withSuccess( IOUtils.resourceToString( "/org/dhis2/fhir/adapter/dhis/test/single-tracked-entity-type.json", StandardCharsets.UTF_8 ), MediaType.APPLICATION_JSON ) ); userDhis2Server.expect( ExpectedCount.once(), method( HttpMethod.GET ) ).andExpect( header( "Authorization", "Basic Zmhpcl9jbGllbnQ6Zmhpcl9jbGllbnRfMQ==" ) ) - .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/programs/EPDyQuoRnXk.json?fields=id,name,code,description,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration," + + .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/programs/EPDyQuoRnXk.json?fields=id,name,code,description,lastUpdated,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration," + "withoutRegistration,captureCoordinates,trackedEntityType%5Bid%5D,programTrackedEntityAttributes%5Bid,name,valueType,mandatory,allowFutureDate,trackedEntityAttribute%5Bid,name,code,valueType,generated%5D%5D,programStages%5Bid,name," + "description,repeatable,captureCoordinates,generatedByEnrollmentDate,minDaysFromStart,programStageDataElements%5Bid,compulsory,allowProvidedElsewhere,dataElement%5Bid,name,code,formName,valueType,optionSetValue,optionSet%5Bid,name," + "options%5Bcode,name%5D%5D%5D%5D%5D" ) ) .andRespond( withSuccess( IOUtils.resourceToString( "/org/dhis2/fhir/adapter/dhis/test/single-program.json", StandardCharsets.UTF_8 ), MediaType.APPLICATION_JSON ) ); userDhis2Server.expect( ExpectedCount.between( 0, 1 ), method( HttpMethod.GET ) ).andExpect( header( "Authorization", "Basic Zmhpcl9jbGllbnQ6Zmhpcl9jbGllbnRfMQ==" ) ) - .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/programs.json?paging=false&fields=id,name,code,description,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration," + + .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/programs.json?paging=false&fields=id,name,code,description,lastUpdated,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration," + "withoutRegistration,captureCoordinates,trackedEntityType%5Bid%5D,programTrackedEntityAttributes%5Bid,name,valueType,mandatory,allowFutureDate,trackedEntityAttribute%5Bid,name,code,valueType,generated%5D%5D,programStages%5Bid,name," + "description,repeatable,captureCoordinates,generatedByEnrollmentDate,minDaysFromStart,programStageDataElements%5Bid,compulsory,allowProvidedElsewhere,dataElement%5Bid,name,code,formName,valueType,optionSetValue,optionSet%5Bid,name," + "options%5Bcode,name%5D%5D%5D%5D%5D" ) ) @@ -146,7 +147,7 @@ private void getPlanDefinitionNotExists() userDhis2Server.reset(); userDhis2Server.expect( ExpectedCount.once(), method( HttpMethod.GET ) ).andExpect( header( "Authorization", "Basic Zmhpcl9jbGllbnQ6Zmhpcl9jbGllbnRfMQ==" ) ) - .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/programs/0dXIdLNUNEn.json?fields=id,name,code,description,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration," + + .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/programs/0dXIdLNUNEn.json?fields=id,name,code,description,lastUpdated,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration," + "withoutRegistration,captureCoordinates,trackedEntityType%5Bid%5D,programTrackedEntityAttributes%5Bid,name,valueType,mandatory,allowFutureDate,trackedEntityAttribute%5Bid,name,code,valueType,generated%5D%5D,programStages%5Bid,name," + "description,repeatable,captureCoordinates,generatedByEnrollmentDate,minDaysFromStart,programStageDataElements%5Bid,compulsory,allowProvidedElsewhere,dataElement%5Bid,name,code,formName,valueType,optionSetValue,optionSet%5Bid,name," + "options%5Bcode,name%5D%5D%5D%5D%5D" ) ) @@ -210,7 +211,7 @@ public void getPlanDefinitionByIdentifierWithoutAuthorization() public void getPlanDefinitionByIdentifierInvalidAuthorization() { userDhis2Server.expect( ExpectedCount.once(), method( HttpMethod.GET ) ).andExpect( header( "Authorization", "Basic Zmhpcl9jbGllbnQ6aW52YWxpZF8x" ) ) - .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/programs.json?paging=false&fields=id,name,code,description,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration,withoutRegistration," + + .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/programs.json?paging=false&fields=id,name,code,description,lastUpdated,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration,withoutRegistration," + "captureCoordinates,trackedEntityType%5Bid%5D,programTrackedEntityAttributes%5Bid,name,valueType,mandatory,allowFutureDate,trackedEntityAttribute%5Bid,name,code,valueType,generated%5D%5D,programStages%5Bid,name,description,repeatable," + "captureCoordinates,generatedByEnrollmentDate,minDaysFromStart,programStageDataElements%5Bid,compulsory,allowProvidedElsewhere,dataElement%5Bid,name,code,formName,valueType,optionSetValue,optionSet%5Bid,name,options%5Bcode," + "name%5D%5D%5D%5D%5D&filter=code:eq:OU_1234" ) ) @@ -238,7 +239,7 @@ private void getPlanDefinitionByIdentifier() throws Exception "fields=id,name,trackedEntityTypeAttributes%5Bid,name,valueType,mandatory,trackedEntityAttribute%5Bid,name,code,valueType,generated,optionSetValue,optionSet%5Bid,name,options%5Bcode,name%5D%5D%5D%5D" ) ) .andRespond( withSuccess( IOUtils.resourceToString( "/org/dhis2/fhir/adapter/dhis/test/single-tracked-entity-type.json", StandardCharsets.UTF_8 ), MediaType.APPLICATION_JSON ) ); userDhis2Server.expect( ExpectedCount.between( 1, 2 ), method( HttpMethod.GET ) ).andExpect( header( "Authorization", "Basic Zmhpcl9jbGllbnQ6Zmhpcl9jbGllbnRfMQ==" ) ) - .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/programs.json?paging=false&fields=id,name,code,description,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration,withoutRegistration," + + .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/programs.json?paging=false&fields=id,name,code,description,lastUpdated,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration,withoutRegistration," + "captureCoordinates,trackedEntityType%5Bid%5D,programTrackedEntityAttributes%5Bid,name,valueType,mandatory,allowFutureDate,trackedEntityAttribute%5Bid,name,code,valueType,generated%5D%5D,programStages%5Bid,name,description,repeatable," + "captureCoordinates,generatedByEnrollmentDate,minDaysFromStart,programStageDataElements%5Bid,compulsory,allowProvidedElsewhere,dataElement%5Bid,name,code,formName,valueType,optionSetValue,optionSet%5Bid,name,options%5Bcode," + "name%5D%5D%5D%5D%5D&filter=code:eq:PD_1234" ) ) @@ -267,7 +268,7 @@ public void searchPlanDefinitionWithoutAuthorization() public void searchPlanDefinitionInvalidAuthorization() { userDhis2Server.expect( ExpectedCount.once(), method( HttpMethod.GET ) ).andExpect( header( "Authorization", "Basic Zmhpcl9jbGllbnQ6aW52YWxpZF8x" ) ) - .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/programs.json?filter=name:$ilike:Test&paging=true&page=1&pageSize=10&order=id&fields=id,name,code,description,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture," + + .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/programs.json?filter=name:$ilike:Test&paging=true&page=1&pageSize=10&order=id&fields=id,name,code,description,lastUpdated,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture," + "displayIncidentDate,registration,withoutRegistration,captureCoordinates,trackedEntityType%5Bid%5D,programTrackedEntityAttributes%5Bid,name,valueType,mandatory,allowFutureDate,trackedEntityAttribute%5Bid,name,code,valueType,generated%5D%5D," + "programStages%5Bid,name,description,repeatable,captureCoordinates,generatedByEnrollmentDate,minDaysFromStart,programStageDataElements%5Bid,compulsory,allowProvidedElsewhere,dataElement%5Bid,name,code,formName,valueType,optionSetValue," + "optionSet%5Bid,name,options%5Bcode,name%5D%5D%5D%5D%5D" ) ) @@ -286,7 +287,7 @@ public void searchPlanDefinition() throws Exception "fields=id,name,trackedEntityTypeAttributes%5Bid,name,valueType,mandatory,trackedEntityAttribute%5Bid,name,code,valueType,generated,optionSetValue,optionSet%5Bid,name,options%5Bcode,name%5D%5D%5D%5D" ) ) .andRespond( withSuccess( IOUtils.resourceToString( "/org/dhis2/fhir/adapter/dhis/test/single-tracked-entity-type.json", StandardCharsets.UTF_8 ), MediaType.APPLICATION_JSON ) ); userDhis2Server.expect( ExpectedCount.once(), method( HttpMethod.GET ) ).andExpect( header( "Authorization", "Basic Zmhpcl9jbGllbnQ6Zmhpcl9jbGllbnRfMQ==" ) ) - .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/programs.json?filter=name:$ilike:Child%20Programme&paging=true&page=1&pageSize=10&order=id&fields=id,name,code,description,selectIncidentDatesInFuture," + + .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/programs.json?filter=name:$ilike:Child%20Programme&paging=true&page=1&pageSize=10&order=id&fields=id,name,code,description,lastUpdated,selectIncidentDatesInFuture," + "selectEnrollmentDatesInFuture,displayIncidentDate,registration,withoutRegistration,captureCoordinates,trackedEntityType%5Bid%5D,programTrackedEntityAttributes%5Bid,name,valueType,mandatory,allowFutureDate,trackedEntityAttribute%5Bid,name," + "code,valueType,generated%5D%5D,programStages%5Bid,name,description,repeatable,captureCoordinates,generatedByEnrollmentDate,minDaysFromStart,programStageDataElements%5Bid,compulsory,allowProvidedElsewhere,dataElement%5Bid,name,code,formName," + "valueType,optionSetValue,optionSet%5Bid,name,options%5Bcode,name%5D%5D%5D%5D%5D" ) ) diff --git a/app/src/test/java/org/dhis2/fhir/adapter/fhir/transform/fhir/impl/enrollment/AbstractEnrollmentTransformationAppTest.java b/app/src/test/java/org/dhis2/fhir/adapter/fhir/transform/fhir/impl/enrollment/AbstractEnrollmentTransformationAppTest.java index f96cac5b..7b0009fc 100644 --- a/app/src/test/java/org/dhis2/fhir/adapter/fhir/transform/fhir/impl/enrollment/AbstractEnrollmentTransformationAppTest.java +++ b/app/src/test/java/org/dhis2/fhir/adapter/fhir/transform/fhir/impl/enrollment/AbstractEnrollmentTransformationAppTest.java @@ -49,13 +49,14 @@ public abstract class AbstractEnrollmentTransformationAppTest extends AbstractAp protected void expectMetadataRequests() throws Exception { systemDhis2Server.expect( ExpectedCount.between( 0, 1 ), method( HttpMethod.GET ) ).andExpect( header( "Authorization", testConfiguration.getDhis2SystemAuthorization() ) ) - .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/programs/EPDyQuoRnXk.json?fields=id,name,code,description,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration," + + .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/programs/EPDyQuoRnXk.json?fields=id,name,code,description,lastUpdated,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration," + "withoutRegistration,captureCoordinates,trackedEntityType%5Bid%5D,programTrackedEntityAttributes%5Bid,name,valueType,mandatory,allowFutureDate,trackedEntityAttribute%5Bid,name,code,valueType,generated%5D%5D,programStages%5Bid,name," + "description,repeatable,captureCoordinates,generatedByEnrollmentDate,minDaysFromStart,programStageDataElements%5Bid,compulsory,allowProvidedElsewhere,dataElement%5Bid,name,code,formName,valueType,optionSetValue,optionSet%5Bid,name," + "options%5Bcode,name%5D%5D%5D%5D%5D" ) ) .andRespond( withSuccess( IOUtils.resourceToString( "/org/dhis2/fhir/adapter/dhis/test/single-program.json", StandardCharsets.UTF_8 ), MediaType.APPLICATION_JSON ) ); systemDhis2Server.expect( ExpectedCount.between( 0, 1 ), method( HttpMethod.GET ) ).andExpect( header( "Authorization", testConfiguration.getDhis2SystemAuthorization() ) ) - .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/programs.json?paging=false&fields=id,name,code,description,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration,withoutRegistration," + + .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/programs.json?paging=false&fields=id,name,code,description,lastUpdated,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration," + + "withoutRegistration," + "captureCoordinates," + "trackedEntityType%5Bid%5D,programTrackedEntityAttributes%5Bid,name,valueType,mandatory,allowFutureDate,trackedEntityAttribute%5Bid,name,code,valueType,generated%5D%5D,programStages%5Bid,name,description,repeatable,captureCoordinates," + "generatedByEnrollmentDate,minDaysFromStart,programStageDataElements%5Bid,compulsory,allowProvidedElsewhere,dataElement%5Bid,name,code,description,formName,valueType,optionSetValue,optionSet%5Bid,name,options%5Bcode," + @@ -74,7 +75,7 @@ protected void expectMetadataRequests() throws Exception .andRespond( withSuccess( IOUtils.resourceToString( "/org/dhis2/fhir/adapter/dhis/test/default-tracked-entity-type.json", StandardCharsets.UTF_8 ), MediaType.APPLICATION_JSON ) ); systemDhis2Server.expect( ExpectedCount.between( 0, 1 ), method( HttpMethod.GET ) ).andExpect( header( "Authorization", testConfiguration.getDhis2SystemAuthorization() ) ) .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/programs.json?paging=false&" + - "fields=id,name,code,description,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration,withoutRegistration,captureCoordinates,trackedEntityType%5Bid%5D,programTrackedEntityAttributes%5Bid,name,valueType," + + "fields=id,name,code,description,lastUpdated,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration,withoutRegistration,captureCoordinates,trackedEntityType%5Bid%5D,programTrackedEntityAttributes%5Bid,name,valueType," + "mandatory,allowFutureDate,trackedEntityAttribute%5Bid,name,code,valueType,generated%5D%5D,programStages%5Bid,name,description,repeatable,captureCoordinates,generatedByEnrollmentDate,minDaysFromStart,programStageDataElements%5Bid,compulsory," + "allowProvidedElsewhere,dataElement%5Bid,name,code,description,formName,valueType,optionSetValue,optionSet%5Bid,name,options%5Bcode,name%5D%5D%5D%5D%5D&filter=name:eq:Child%20Programme" ) ) .andRespond( withSuccess( IOUtils.resourceToString( "/org/dhis2/fhir/adapter/dhis/test/single-program.json", StandardCharsets.UTF_8 ), MediaType.APPLICATION_JSON ) ); diff --git a/app/src/test/java/org/dhis2/fhir/adapter/fhir/transform/fhir/impl/programstage/AbstractProgramStageTransformationAppTest.java b/app/src/test/java/org/dhis2/fhir/adapter/fhir/transform/fhir/impl/programstage/AbstractProgramStageTransformationAppTest.java index b104bc05..742bfca8 100644 --- a/app/src/test/java/org/dhis2/fhir/adapter/fhir/transform/fhir/impl/programstage/AbstractProgramStageTransformationAppTest.java +++ b/app/src/test/java/org/dhis2/fhir/adapter/fhir/transform/fhir/impl/programstage/AbstractProgramStageTransformationAppTest.java @@ -50,7 +50,8 @@ public abstract class AbstractProgramStageTransformationAppTest extends Abstract protected void expectMetadataRequests() throws Exception { systemDhis2Server.expect( ExpectedCount.between( 0, 1 ), method( HttpMethod.GET ) ).andExpect( header( "Authorization", testConfiguration.getDhis2SystemAuthorization() ) ) - .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/programs.json?paging=false&fields=id,name,code,description,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration,withoutRegistration," + + .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/programs.json?paging=false&fields=id,name,code,description,lastUpdated,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration," + + "withoutRegistration," + "captureCoordinates,trackedEntityType%5Bid%5D,programTrackedEntityAttributes%5Bid,name,valueType,mandatory,allowFutureDate,trackedEntityAttribute%5Bid,name,code,valueType,generated%5D%5D,programStages%5Bid,name,description,repeatable," + "captureCoordinates," + "generatedByEnrollmentDate,minDaysFromStart,programStageDataElements%5Bid,compulsory,allowProvidedElsewhere,dataElement%5Bid,name,code,formName,valueType,optionSetValue,optionSet%5Bid,name,options%5Bcode," + @@ -69,7 +70,7 @@ protected void expectMetadataRequests() throws Exception .andRespond( withSuccess( IOUtils.resourceToString( "/org/dhis2/fhir/adapter/dhis/test/default-tracked-entity-type.json", StandardCharsets.UTF_8 ), MediaType.APPLICATION_JSON ) ); systemDhis2Server.expect( ExpectedCount.between( 0, 1 ), method( HttpMethod.GET ) ).andExpect( header( "Authorization", testConfiguration.getDhis2SystemAuthorization() ) ) .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/programs.json?paging=false&" + - "fields=id,name,code,description,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration,withoutRegistration,captureCoordinates,trackedEntityType%5Bid%5D,programTrackedEntityAttributes%5Bid,name,valueType," + + "fields=id,name,code,description,lastUpdated,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration,withoutRegistration,captureCoordinates,trackedEntityType%5Bid%5D,programTrackedEntityAttributes%5Bid,name,valueType," + "mandatory,allowFutureDate,trackedEntityAttribute%5Bid,name,code,valueType,generated%5D%5D,programStages%5Bid,name,description,repeatable,captureCoordinates,generatedByEnrollmentDate,minDaysFromStart,programStageDataElements%5Bid,compulsory," + "allowProvidedElsewhere,dataElement%5Bid,name,code,description,formName,valueType,optionSetValue,optionSet%5Bid,name,options%5Bcode,name%5D%5D%5D%5D%5D&filter=name:eq:Child%20Programme" ) ) .andRespond( withSuccess( IOUtils.resourceToString( "/org/dhis2/fhir/adapter/dhis/test/single-program.json", StandardCharsets.UTF_8 ), MediaType.APPLICATION_JSON ) ); diff --git a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/model/DhisResourceType.java b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/model/DhisResourceType.java index 80d8238f..30e669e9 100644 --- a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/model/DhisResourceType.java +++ b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/model/DhisResourceType.java @@ -36,20 +36,16 @@ /** * Contains the different types of DHIS2 Resources that are can be created. + * The enum values should be listed in the order of the dependencies. * * @author volsch */ public enum DhisResourceType { /** - * Resource is a tracked entity instance. - */ - TRACKED_ENTITY( "trackedEntityInstances", "te", "TrackedEntityRule" ), - - /** - * Resource is a tracked entity type. + * Resource is a organisation unit. */ - TRACKED_ENTITY_TYPE( "trackedEntityTypes", "tt", "TrackedEntityTypeRule" ), + ORGANIZATION_UNIT( "organisationUnits", "ou", "OrganizationUnitRule" ), /** * The program metadata. @@ -61,20 +57,26 @@ public enum DhisResourceType */ PROGRAM_STAGE_METADATA( "programStages", "sm", "ProgramStageMetadataRule" ), + /** - * Resource is a program instance (aka enrollment). + * Resource is a tracked entity type. */ - ENROLLMENT( "enrollments", "en", "EnrollmentRule" ), + TRACKED_ENTITY_TYPE( "trackedEntityTypes", "tt", "TrackedEntityTypeRule" ), /** - * Resource is a program stage instance (aka event of a program instance). + * Resource is a tracked entity instance. */ - PROGRAM_STAGE_EVENT( "events", "ps", "ProgramStageRule" ), + TRACKED_ENTITY( "trackedEntityInstances", "te", "TrackedEntityRule" ), /** - * Resource is a organisation unit. + * Resource is a program instance (aka enrollment). + */ + ENROLLMENT( "enrollments", "en", "EnrollmentRule" ), + + /** + * Resource is a program stage instance (aka event of a program instance). */ - ORGANIZATION_UNIT( "organisationUnits", "ou", "OrganizationUnitRule" ); + PROGRAM_STAGE_EVENT( "events", "ps", "ProgramStageRule" ); private static final Map byTypeName = Arrays.stream( values() ).collect( Collectors.toMap( DhisResourceType::getTypeName, v -> v ) ); diff --git a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/orgunit/impl/OrganizationUnitServiceImpl.java b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/orgunit/impl/OrganizationUnitServiceImpl.java index c0839e5d..da9839d4 100644 --- a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/orgunit/impl/OrganizationUnitServiceImpl.java +++ b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/orgunit/impl/OrganizationUnitServiceImpl.java @@ -58,7 +58,7 @@ public OrganizationUnitServiceImpl( @Nonnull @Qualifier( "systemDhis2RestTemplat @Nonnull @Override - protected DhisResourceType getDhisResourceType() + public DhisResourceType getDhisResourceType() { return DhisResourceType.ORGANIZATION_UNIT; } diff --git a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/service/DhisMetadataService.java b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/service/DhisMetadataService.java index e36d5ce3..2e2e08ae 100644 --- a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/service/DhisMetadataService.java +++ b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/service/DhisMetadataService.java @@ -28,8 +28,6 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import org.dhis2.fhir.adapter.data.model.ProcessedItemInfo; -import org.dhis2.fhir.adapter.dhis.metadata.model.DhisSyncGroup; import org.dhis2.fhir.adapter.dhis.model.DhisMetadata; import org.dhis2.fhir.adapter.dhis.model.DhisResource; import org.dhis2.fhir.adapter.dhis.model.DhisResourceResult; @@ -37,11 +35,7 @@ import org.dhis2.fhir.adapter.dhis.model.UriFilterApplier; import javax.annotation.Nonnull; -import java.time.Instant; -import java.util.Collection; import java.util.Optional; -import java.util.Set; -import java.util.function.Consumer; /** * Service that provides access to DHIS2 metadata. @@ -49,7 +43,7 @@ * @param the concrete type of the metadata. * @author volsch */ -public interface DhisMetadataService +public interface DhisMetadataService extends DhisPolledService, DhisService { @Nonnull Optional findMetadataByReference( @Nonnull Reference reference ); @@ -62,8 +56,4 @@ public interface DhisMetadataService @Nonnull DhisResourceResult find( @Nonnull UriFilterApplier uriFilterApplier, int from, int max ); - - @Nonnull - Instant poll( @Nonnull DhisSyncGroup group, @Nonnull Instant lastUpdated, int toleranceMillis, - int maxSearchCount, @Nonnull Set excludedStoredBy, @Nonnull Consumer> consumer ); } diff --git a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/service/DhisPolledService.java b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/service/DhisPolledService.java new file mode 100644 index 00000000..87a7481f --- /dev/null +++ b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/service/DhisPolledService.java @@ -0,0 +1,52 @@ +package org.dhis2.fhir.adapter.dhis.service; + +/* + * Copyright (c) 2004-2019, 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. + */ + +import org.dhis2.fhir.adapter.data.model.ProcessedItemInfo; +import org.dhis2.fhir.adapter.dhis.metadata.model.DhisSyncGroup; +import org.dhis2.fhir.adapter.dhis.model.DhisResource; + +import javax.annotation.Nonnull; +import java.time.Instant; +import java.util.Collection; +import java.util.Set; +import java.util.function.Consumer; + +/** + * Service that provides polled access to DHIS2 data. + * + * @param the concrete type of the data. + * @author volsch + */ +public interface DhisPolledService extends DhisService +{ + @Nonnull + Instant poll( @Nonnull DhisSyncGroup group, @Nonnull Instant lastUpdated, int toleranceMillis, + int maxSearchCount, @Nonnull Set excludedStoredBy, @Nonnull Consumer> consumer ); +} diff --git a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/service/DhisService.java b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/service/DhisService.java new file mode 100644 index 00000000..9eaf55ba --- /dev/null +++ b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/service/DhisService.java @@ -0,0 +1,46 @@ +package org.dhis2.fhir.adapter.dhis.service; + +/* + * Copyright (c) 2004-2019, 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. + */ + +import org.dhis2.fhir.adapter.dhis.model.DhisResource; +import org.dhis2.fhir.adapter.dhis.model.DhisResourceType; + +import javax.annotation.Nonnull; + +/** + * Service that provides access to DHIS2 data. + * + * @param the concrete type of the DHIS2 resource. + * @author volsch + */ +public interface DhisService +{ + @Nonnull + DhisResourceType getDhisResourceType(); +} diff --git a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/service/impl/AbstractDhisMetadataServiceImpl.java b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/service/impl/AbstractDhisMetadataServiceImpl.java index 767102db..fc466c7b 100644 --- a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/service/impl/AbstractDhisMetadataServiceImpl.java +++ b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/service/impl/AbstractDhisMetadataServiceImpl.java @@ -91,7 +91,7 @@ protected AbstractDhisMetadataServiceImpl( @Nonnull @Qualifier( "systemDhis2Rest } @Nonnull - protected abstract DhisResourceType getDhisResourceType(); + public abstract DhisResourceType getDhisResourceType(); @Nonnull protected abstract Class getItemClass(); diff --git a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/sync/impl/DhisDataProcessorItemRetrieverImpl.java b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/sync/impl/DhisDataProcessorItemRetrieverImpl.java index 6a655afa..9f59da2c 100644 --- a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/sync/impl/DhisDataProcessorItemRetrieverImpl.java +++ b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/sync/impl/DhisDataProcessorItemRetrieverImpl.java @@ -36,20 +36,25 @@ import org.dhis2.fhir.adapter.data.processor.DataProcessorItemRetriever; import org.dhis2.fhir.adapter.dhis.config.DhisConfig; import org.dhis2.fhir.adapter.dhis.metadata.model.DhisSyncGroup; +import org.dhis2.fhir.adapter.dhis.model.DhisResource; import org.dhis2.fhir.adapter.dhis.model.DhisResourceType; -import org.dhis2.fhir.adapter.dhis.orgunit.OrganizationUnitService; +import org.dhis2.fhir.adapter.dhis.service.DhisPolledService; +import org.dhis2.fhir.adapter.dhis.service.DhisService; import org.dhis2.fhir.adapter.dhis.sync.SyncExcludedDhisUsernameRetriever; -import org.dhis2.fhir.adapter.dhis.tracker.program.EventService; -import org.dhis2.fhir.adapter.dhis.tracker.program.ProgramMetadataService; -import org.dhis2.fhir.adapter.dhis.tracker.trackedentity.TrackedEntityService; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; import javax.annotation.Nonnull; import java.time.Instant; import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.Set; +import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; /** * The item retriever that polls DHIS2 resources. All relevant resources are @@ -66,13 +71,7 @@ public class DhisDataProcessorItemRetrieverImpl implements DataProcessorItemRetr private final Authorization systemDhis2Authorization; - private final OrganizationUnitService organizationUnitService; - - private final ProgramMetadataService programMetadataService; - - private final TrackedEntityService trackedEntityService; - - private final EventService eventService; + private final Map> polledServices; private final DhisSyncProcessorConfig processorConfig; @@ -80,20 +79,14 @@ public DhisDataProcessorItemRetrieverImpl( @Nonnull AuthorizationContext authorizationContext, @Nonnull @Qualifier( "systemDhis2Authorization" ) Authorization systemDhis2Authorization, @Nonnull SyncExcludedDhisUsernameRetriever excludedDhisUsernameRetriever, - @Nonnull OrganizationUnitService organizationUnitService, - @Nonnull ProgramMetadataService programMetadataService, - @Nonnull TrackedEntityService trackedEntityService, - @Nonnull EventService eventService, + @Nonnull List> polledServices, @Nonnull DhisSyncProcessorConfig processorConfig, @Nonnull DhisConfig config ) { this.authorizationContext = authorizationContext; this.systemDhis2Authorization = systemDhis2Authorization; this.excludedDhisUsernameRetriever = excludedDhisUsernameRetriever; - this.trackedEntityService = trackedEntityService; - this.eventService = eventService; - this.organizationUnitService = organizationUnitService; - this.programMetadataService = programMetadataService; + this.polledServices = polledServices.stream().collect( Collectors.toMap( DhisService::getDhisResourceType, ps -> ps ) ); this.processorConfig = processorConfig; } @@ -103,38 +96,21 @@ public Instant poll( @Nonnull DhisSyncGroup group, @Nonnull Instant lastUpdated, { final int toleranceMillis = processorConfig.getToleranceMillis(); final Set resourceTypes = processorConfig.getResourceTypes(); + authorizationContext.setAuthorization( systemDhis2Authorization ); try { final Set excludedDhisUsernames = excludedDhisUsernameRetriever.findAllDhisUsernames(); - Instant result = Instant.now(); + final AtomicReference result = new AtomicReference<>( Instant.now() ); - if ( resourceTypes.contains( DhisResourceType.ORGANIZATION_UNIT ) ) - { - final Instant currentResult = organizationUnitService.poll( group, lastUpdated, toleranceMillis, maxSearchCount, - excludedDhisUsernames, consumer ); - result = ObjectUtils.min( result, currentResult ); - } - if ( resourceTypes.contains( DhisResourceType.PROGRAM_METADATA ) ) - { - final Instant currentResult = programMetadataService.poll( group, lastUpdated, toleranceMillis, maxSearchCount, - excludedDhisUsernames, consumer ); - result = ObjectUtils.min( result, currentResult ); - } - if ( resourceTypes.contains( DhisResourceType.TRACKED_ENTITY ) ) - { - final Instant currentResult = trackedEntityService.poll( group, lastUpdated, toleranceMillis, maxSearchCount, - excludedDhisUsernames, consumer ); - result = ObjectUtils.min( result, currentResult ); - } - if ( resourceTypes.contains( DhisResourceType.PROGRAM_STAGE_EVENT ) ) - { - final Instant currentResult = eventService.poll( group, lastUpdated, toleranceMillis, maxSearchCount, - excludedDhisUsernames, consumer ); - result = ObjectUtils.min( result, currentResult ); - } + Stream.of( DhisResourceType.values() ).filter( resourceTypes::contains ).map( polledServices::get ).filter( Objects::nonNull ) + .forEach( polledService -> { + final Instant currentResult = polledService.poll( group, lastUpdated, toleranceMillis, maxSearchCount, + excludedDhisUsernames, consumer ); + result.set( ObjectUtils.min( result.get(), currentResult ) ); + } ); - return result; + return result.get(); } finally { diff --git a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/EnrollmentService.java b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/EnrollmentService.java index 4326ea09..fa3db68c 100644 --- a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/EnrollmentService.java +++ b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/EnrollmentService.java @@ -28,6 +28,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +import org.dhis2.fhir.adapter.dhis.service.DhisService; + import javax.annotation.Nonnull; import java.util.Optional; @@ -38,7 +40,7 @@ * @author volsch * @author Charles Chigoriwa (ITINORDIC) */ -public interface EnrollmentService +public interface EnrollmentService extends DhisService { @Nonnull Optional findLatestActiveRefreshed( @Nonnull String programId, @Nonnull String trackedEntityInstanceId, boolean localOnly ); diff --git a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/EventService.java b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/EventService.java index 99582bae..80215e74 100644 --- a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/EventService.java +++ b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/EventService.java @@ -28,17 +28,14 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import org.dhis2.fhir.adapter.data.model.ProcessedItemInfo; -import org.dhis2.fhir.adapter.dhis.metadata.model.DhisSyncGroup; import org.dhis2.fhir.adapter.dhis.model.DhisResourceResult; import org.dhis2.fhir.adapter.dhis.model.UriFilterApplier; +import org.dhis2.fhir.adapter.dhis.service.DhisPolledService; +import org.dhis2.fhir.adapter.dhis.service.DhisService; import javax.annotation.Nonnull; -import java.time.Instant; import java.util.Collection; import java.util.Optional; -import java.util.Set; -import java.util.function.Consumer; /** * Service to create, update and read DHIS2 Program Stage Instances (aka events) @@ -46,7 +43,7 @@ * * @author volsch */ -public interface EventService +public interface EventService extends DhisService, DhisPolledService { @Nonnull Collection findRefreshed( @Nonnull String programId, @Nonnull String programStageId, @@ -69,8 +66,4 @@ Collection find( @Nonnull String programId, @Nonnull String programStageI @Nonnull DhisResourceResult find( @Nonnull String programId, @Nonnull String programStageId, @Nonnull UriFilterApplier uriFilterApplier, int from, int max ); - - @Nonnull - Instant poll( @Nonnull DhisSyncGroup group, @Nonnull Instant lastUpdated, int toleranceMillis, - int maxSearchCount, @Nonnull Set excludedStoredBy, @Nonnull Consumer> consumer ); } diff --git a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/WritableProgram.java b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/WritableProgram.java index b6327539..457168ae 100644 --- a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/WritableProgram.java +++ b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/WritableProgram.java @@ -50,6 +50,8 @@ public class WritableProgram extends AbstractDhisMetadata implements Program, Se { private static final long serialVersionUID = -4906529875383953995L; + private ZonedDateTime lastUpdated; + @JsonInclude( JsonInclude.Include.NON_NULL ) private String id; @@ -294,7 +296,7 @@ public boolean isDeleted() @Override public ZonedDateTime getLastUpdated() { - return null; + return lastUpdated; } @Override diff --git a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/impl/EnrollmentServiceImpl.java b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/impl/EnrollmentServiceImpl.java index 1e33b3a5..b5067391 100644 --- a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/impl/EnrollmentServiceImpl.java +++ b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/impl/EnrollmentServiceImpl.java @@ -39,6 +39,7 @@ import org.dhis2.fhir.adapter.dhis.local.LocalDhisRepositoryPersistStatus; import org.dhis2.fhir.adapter.dhis.local.LocalDhisResourceRepositoryTemplate; import org.dhis2.fhir.adapter.dhis.model.DhisResourceComparator; +import org.dhis2.fhir.adapter.dhis.model.DhisResourceType; import org.dhis2.fhir.adapter.dhis.model.ImportStatus; import org.dhis2.fhir.adapter.dhis.model.ImportSummaries; import org.dhis2.fhir.adapter.dhis.model.ImportSummary; @@ -117,6 +118,13 @@ public EnrollmentServiceImpl( @Nonnull @Qualifier( "userDhis2RestTemplate" ) Res this.resourceRepositoryTemplate = new LocalDhisResourceRepositoryTemplate<>( Enrollment.class, requestCacheService, this ); } + @Nonnull + @Override + public DhisResourceType getDhisResourceType() + { + return DhisResourceType.ENROLLMENT; + } + @HystrixCommand( ignoreExceptions = UnauthorizedException.class ) @Nonnull @Override diff --git a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/impl/EventServiceImpl.java b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/impl/EventServiceImpl.java index fc9b8fc7..5799e5b4 100644 --- a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/impl/EventServiceImpl.java +++ b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/impl/EventServiceImpl.java @@ -45,6 +45,7 @@ import org.dhis2.fhir.adapter.dhis.model.DataValue; import org.dhis2.fhir.adapter.dhis.model.DhisResourceComparator; import org.dhis2.fhir.adapter.dhis.model.DhisResourceResult; +import org.dhis2.fhir.adapter.dhis.model.DhisResourceType; import org.dhis2.fhir.adapter.dhis.model.ImportStatus; import org.dhis2.fhir.adapter.dhis.model.ImportSummary; import org.dhis2.fhir.adapter.dhis.model.ImportSummaryWebMessage; @@ -136,6 +137,13 @@ public EventServiceImpl( @Nonnull @Qualifier( "userDhis2RestTemplate" ) RestTemp this.resourceRepositoryTemplate = new LocalDhisResourceRepositoryTemplate<>( Event.class, requestCacheService, this ); } + @Nonnull + @Override + public DhisResourceType getDhisResourceType() + { + return DhisResourceType.PROGRAM_STAGE_EVENT; + } + @HystrixCommand( ignoreExceptions = { DhisConflictException.class, UnauthorizedException.class } ) @Override public boolean delete( @Nonnull String eventId ) diff --git a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/impl/ProgramMetadataServiceImpl.java b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/impl/ProgramMetadataServiceImpl.java index 070f1d71..a17179c8 100644 --- a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/impl/ProgramMetadataServiceImpl.java +++ b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/impl/ProgramMetadataServiceImpl.java @@ -49,7 +49,7 @@ public class ProgramMetadataServiceImpl extends AbstractDhisMetadataServiceImpl implements ProgramMetadataService { protected static final String FIELDS = - "id,name,code,description,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate," + + "id,name,code,description,lastUpdated,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate," + "registration,withoutRegistration,captureCoordinates,trackedEntityType[id]," + "programTrackedEntityAttributes[id,name,valueType,mandatory,allowFutureDate," + "trackedEntityAttribute[id,name,code,valueType,generated]]," + @@ -64,7 +64,7 @@ public ProgramMetadataServiceImpl( @Nonnull @Qualifier( "systemDhis2RestTemplate @Nonnull @Override - protected DhisResourceType getDhisResourceType() + public DhisResourceType getDhisResourceType() { return DhisResourceType.PROGRAM_METADATA; } diff --git a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/trackedentity/TrackedEntityService.java b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/trackedentity/TrackedEntityService.java index 34688f99..c8348eac 100644 --- a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/trackedentity/TrackedEntityService.java +++ b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/trackedentity/TrackedEntityService.java @@ -28,25 +28,22 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import org.dhis2.fhir.adapter.data.model.ProcessedItemInfo; -import org.dhis2.fhir.adapter.dhis.metadata.model.DhisSyncGroup; import org.dhis2.fhir.adapter.dhis.model.DhisResourceResult; import org.dhis2.fhir.adapter.dhis.model.UriFilterApplier; +import org.dhis2.fhir.adapter.dhis.service.DhisPolledService; +import org.dhis2.fhir.adapter.dhis.service.DhisService; import javax.annotation.Nonnull; -import java.time.Instant; import java.util.Collection; import java.util.Map; import java.util.Optional; -import java.util.Set; -import java.util.function.Consumer; /** * Service that allows to create, read and update tracked entity instances. * * @author volsch */ -public interface TrackedEntityService +public interface TrackedEntityService extends DhisService, DhisPolledService { void updateGeneratedValues( @Nonnull TrackedEntityInstance trackedEntityInstance, @Nonnull TrackedEntityType type, @Nonnull Map requiredValues ); @@ -74,8 +71,4 @@ Collection findByAttrValue( @Nonnull String typeId, @Nonnull DhisResourceResult find( @Nonnull String trackedEntityTypeId, @Nonnull UriFilterApplier uriFilterApplier, int from, int max ); - - @Nonnull - Instant poll( @Nonnull DhisSyncGroup group, @Nonnull Instant lastUpdated, int toleranceMillis, - int maxSearchCount, @Nonnull Set excludedStoredBy, @Nonnull Consumer> consumer ); } diff --git a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/trackedentity/impl/TrackedEntityServiceImpl.java b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/trackedentity/impl/TrackedEntityServiceImpl.java index beda50e6..7c8102f0 100644 --- a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/trackedentity/impl/TrackedEntityServiceImpl.java +++ b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/trackedentity/impl/TrackedEntityServiceImpl.java @@ -154,6 +154,13 @@ public TrackedEntityServiceImpl( @Nonnull @Qualifier( "userDhis2RestTemplate" ) this.resourceRepositoryTemplate = new LocalDhisResourceRepositoryTemplate<>( TrackedEntityInstance.class, requestCacheService, this ); } + @Nonnull + @Override + public DhisResourceType getDhisResourceType() + { + return DhisResourceType.TRACKED_ENTITY; + } + @HystrixCommand( ignoreExceptions = { DhisConflictException.class, UnauthorizedException.class } ) @Override public void updateGeneratedValues( @Nonnull TrackedEntityInstance trackedEntityInstance, @Nonnull TrackedEntityType type, @Nonnull Map requiredValues ) diff --git a/dhis/src/test/java/org/dhis2/fhir/adapter/dhis/tracker/program/impl/ProgramMetadataServiceImplTest.java b/dhis/src/test/java/org/dhis2/fhir/adapter/dhis/tracker/program/impl/ProgramMetadataServiceImplTest.java index b1aabe2f..27653d09 100644 --- a/dhis/src/test/java/org/dhis2/fhir/adapter/dhis/tracker/program/impl/ProgramMetadataServiceImplTest.java +++ b/dhis/src/test/java/org/dhis2/fhir/adapter/dhis/tracker/program/impl/ProgramMetadataServiceImplTest.java @@ -81,7 +81,8 @@ public void setUp() @Test public void findMetadataByReferenceId() throws IOException { - mockServer.expect( requestTo( "http://localhost:8080/api/programs/93783.json?fields=id,name,code,description,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration,withoutRegistration,captureCoordinates," + + mockServer.expect( requestTo( "http://localhost:8080/api/programs/93783.json?fields=id,name,code,description,lastUpdated,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration,withoutRegistration," + + "captureCoordinates," + "trackedEntityType%5Bid%5D,programTrackedEntityAttributes%5Bid,name,valueType,mandatory,allowFutureDate,trackedEntityAttribute%5Bid,name,code,valueType,generated%5D%5D,programStages%5Bid,name,description,repeatable,captureCoordinates," + "generatedByEnrollmentDate,minDaysFromStart,programStageDataElements%5Bid,compulsory,allowProvidedElsewhere,dataElement%5Bid,name,code,formName,valueType,optionSetValue,optionSet%5Bid,name,options%5Bcode,name%5D%5D%5D%5D%5D" ) ) .andExpect( method( HttpMethod.GET ) ).andRespond( withSuccess( IOUtils.resourceToByteArray( "/org/dhis2/fhir/adapter/dhis/tracker/program/impl/program.json" ), MediaType.APPLICATION_JSON ) ); @@ -94,7 +95,7 @@ public void findMetadataByReferenceId() throws IOException @Test public void findMetadataByReferenceIdNotFound() { - mockServer.expect( requestTo( "http://localhost:8080/api/programs/93783.json?fields=id,name,code,description,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration,withoutRegistration,captureCoordinates," + + mockServer.expect( requestTo( "http://localhost:8080/api/programs/93783.json?fields=id,name,code,description,lastUpdated,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration,withoutRegistration,captureCoordinates," + "trackedEntityType%5Bid%5D,programTrackedEntityAttributes%5Bid,name,valueType,mandatory,allowFutureDate,trackedEntityAttribute%5Bid,name,code,valueType,generated%5D%5D,programStages%5Bid,name,description,repeatable,captureCoordinates," + "generatedByEnrollmentDate,minDaysFromStart,programStageDataElements%5Bid,compulsory,allowProvidedElsewhere,dataElement%5Bid,name,code,formName,valueType,optionSetValue,optionSet%5Bid,name,options%5Bcode,name%5D%5D%5D%5D%5D" ) ).andExpect( method( HttpMethod.GET ) ) .andRespond( MockRestResponseCreators.withStatus( HttpStatus.NOT_FOUND ).body( "{}" ).contentType( MediaType.APPLICATION_JSON ) ); @@ -106,7 +107,7 @@ public void findMetadataByReferenceIdNotFound() @Test( expected = HttpServerErrorException.class ) public void findMetadataByReferenceIdServerError() { - mockServer.expect( requestTo( "http://localhost:8080/api/programs/93783.json?fields=id,name,code,description,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration,withoutRegistration,captureCoordinates," + + mockServer.expect( requestTo( "http://localhost:8080/api/programs/93783.json?fields=id,name,code,description,lastUpdated,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration,withoutRegistration,captureCoordinates," + "trackedEntityType%5Bid%5D,programTrackedEntityAttributes%5Bid,name,valueType,mandatory,allowFutureDate,trackedEntityAttribute%5Bid,name,code,valueType,generated%5D%5D,programStages%5Bid,name,description,repeatable,captureCoordinates," + "generatedByEnrollmentDate,minDaysFromStart,programStageDataElements%5Bid,compulsory,allowProvidedElsewhere,dataElement%5Bid,name,code,formName,valueType,optionSetValue,optionSet%5Bid,name,options%5Bcode,name%5D%5D%5D%5D%5D" ) ).andExpect( method( HttpMethod.GET ) ) .andRespond( MockRestResponseCreators.withServerError() ); @@ -116,7 +117,7 @@ public void findMetadataByReferenceIdServerError() @Test public void findMetadataByReferenceCode() throws IOException { - mockServer.expect( requestTo( "http://localhost:8080/api/programs.json?paging=false&fields=id,name,code,description,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration,withoutRegistration,captureCoordinates," + + mockServer.expect( requestTo( "http://localhost:8080/api/programs.json?paging=false&fields=id,name,code,description,lastUpdated,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration,withoutRegistration,captureCoordinates," + "trackedEntityType%5Bid%5D,programTrackedEntityAttributes%5Bid,name,valueType,mandatory,allowFutureDate,trackedEntityAttribute%5Bid,name,code,valueType,generated%5D%5D,programStages%5Bid,name,description,repeatable,captureCoordinates," + "generatedByEnrollmentDate,minDaysFromStart,programStageDataElements%5Bid,compulsory,allowProvidedElsewhere,dataElement%5Bid,name,code,formName,valueType,optionSetValue,optionSet%5Bid,name,options%5Bcode," + "name%5D%5D%5D%5D%5D&filter=code:eq:OU_3783" ) ).andExpect( method( HttpMethod.GET ) ) @@ -130,7 +131,7 @@ public void findMetadataByReferenceCode() throws IOException @Test public void findMetadataByReferenceCodeNotFound() throws IOException { - mockServer.expect( requestTo( "http://localhost:8080/api/programs.json?paging=false&fields=id,name,code,description,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration,withoutRegistration,captureCoordinates," + + mockServer.expect( requestTo( "http://localhost:8080/api/programs.json?paging=false&fields=id,name,code,description,lastUpdated,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration,withoutRegistration,captureCoordinates," + "trackedEntityType%5Bid%5D,programTrackedEntityAttributes%5Bid,name,valueType,mandatory,allowFutureDate,trackedEntityAttribute%5Bid,name,code,valueType,generated%5D%5D,programStages%5Bid,name,description,repeatable,captureCoordinates," + "generatedByEnrollmentDate,minDaysFromStart,programStageDataElements%5Bid,compulsory,allowProvidedElsewhere,dataElement%5Bid,name,code,formName,valueType,optionSetValue,optionSet%5Bid,name,options%5Bcode," + "name%5D%5D%5D%5D%5D&filter=code:eq:OU_3783" ) ).andExpect( method( HttpMethod.GET ) ) @@ -143,7 +144,7 @@ public void findMetadataByReferenceCodeNotFound() throws IOException @Test public void findMetadataByReferenceName() throws IOException { - mockServer.expect( requestTo( "http://localhost:8080/api/programs.json?paging=false&fields=id,name,code,description,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration,withoutRegistration,captureCoordinates," + + mockServer.expect( requestTo( "http://localhost:8080/api/programs.json?paging=false&fields=id,name,code,description,lastUpdated,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration,withoutRegistration,captureCoordinates," + "trackedEntityType%5Bid%5D,programTrackedEntityAttributes%5Bid,name,valueType,mandatory,allowFutureDate,trackedEntityAttribute%5Bid,name,code,valueType,generated%5D%5D,programStages%5Bid,name,description,repeatable,captureCoordinates," + "generatedByEnrollmentDate,minDaysFromStart,programStageDataElements%5Bid,compulsory,allowProvidedElsewhere,dataElement%5Bid,name,code,formName,valueType,optionSetValue,optionSet%5Bid,name,options%5Bcode," + "name%5D%5D%5D%5D%5D&filter=name:eq:Freetown" ) ).andExpect( method( HttpMethod.GET ) ) @@ -157,7 +158,7 @@ public void findMetadataByReferenceName() throws IOException @Test public void findMetadataByReferenceNameNotFound() throws IOException { - mockServer.expect( requestTo( "http://localhost:8080/api/programs.json?paging=false&fields=id,name,code,description,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration,withoutRegistration,captureCoordinates," + + mockServer.expect( requestTo( "http://localhost:8080/api/programs.json?paging=false&fields=id,name,code,description,lastUpdated,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration,withoutRegistration,captureCoordinates," + "trackedEntityType%5Bid%5D,programTrackedEntityAttributes%5Bid,name,valueType,mandatory,allowFutureDate,trackedEntityAttribute%5Bid,name,code,valueType,generated%5D%5D,programStages%5Bid,name,description,repeatable,captureCoordinates," + "generatedByEnrollmentDate,minDaysFromStart,programStageDataElements%5Bid,compulsory,allowProvidedElsewhere,dataElement%5Bid,name,code,formName,valueType,optionSetValue,optionSet%5Bid,name,options%5Bcode," + "name%5D%5D%5D%5D%5D&filter=name:eq:Freetown" ) ).andExpect( method( HttpMethod.GET ) ) diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/AbstractDhisToFhirTransformer.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/AbstractDhisToFhirTransformer.java index ed19b435..91e0517c 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/AbstractDhisToFhirTransformer.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/AbstractDhisToFhirTransformer.java @@ -250,7 +250,7 @@ protected Optional getResource( @Nonnull FhirClient fhi } @Nonnull - protected String createDhisFhirResourceId( @Nonnull RuleInfo ruleInfo, @Nonnull ScriptedDhisResource dhisResource ) + protected String createDhisFhirResourceId( @Nonnull RuleInfo ruleInfo, @Nonnull ScriptedDhisResource dhisResource ) { if ( ruleInfo.getRule().isSimpleFhirId() ) { @@ -532,10 +532,9 @@ protected boolean evaluateNotModified( @Nonnull DhisToFhirTransformerContext con } @Nonnull - protected String createAdapterIdentifierValue( @Nonnull RuleInfo rule, @Nonnull ScriptedDhisResource dhisResource ) + protected String createAdapterIdentifierValue( @Nonnull RuleInfo ruleInfo, @Nonnull ScriptedDhisResource dhisResource ) { - return DhisFhirResourceId.toString( rule.getRule().getDhisResourceType(), - Objects.requireNonNull( dhisResource.getId() ), rule.getRule().getId() ); + return createDhisFhirResourceId( ruleInfo, dhisResource ); } @Nullable