From 8fb32c8af23fb5cf01bc759007f085b51a12137c Mon Sep 17 00:00:00 2001 From: Volker Schmidt Date: Tue, 23 Jul 2019 23:13:11 +0200 Subject: [PATCH] Prepares transformer classes split for easier handling of metadata. --- .../dhis/config/DhisMetadataCacheConfig.java | 32 ++- ...hisType.java => AbstractDhisMetadata.java} | 4 +- .../fhir/adapter/dhis/model/DataElement.java | 2 +- .../{DhisType.java => DhisMetadata.java} | 8 +- .../dhis/model/WritableDataElement.java | 2 +- .../dhis/orgunit/OrganizationUnit.java | 4 +- .../dhis/orgunit/OrganizationUnitService.java | 30 +-- .../orgunit/impl/DhisOrganizationUnits.java | 29 +-- .../impl/OrganizationUnitServiceImpl.java | 134 ++--------- .../fhir/adapter/dhis/poll/PolledItems.java | 3 +- .../dhis/service/DhisMetadataService.java | 69 ++++++ .../impl/AbstractDhisMetadataServiceImpl.java | 208 ++++++++++++++++++ .../dhis/service/impl/DhisMetadataItems.java | 82 +++++++ .../impl/DhisMetadataPolledItem.java} | 8 +- .../DhisMetadataPolledItemDeserializer.java | 77 +++++++ .../DhisMetadataPolledItemRetriever.java} | 21 +- .../impl/DhisMetadataPolledItems.java} | 28 +-- .../adapter/dhis/tracker/program/Program.java | 4 +- .../program/ProgramMetadataService.java | 16 +- .../dhis/tracker/program/ProgramStage.java | 4 +- .../dhis/tracker/program/WritableProgram.java | 4 +- .../tracker/program/WritableProgramStage.java | 4 +- .../tracker/program/impl/DhisPrograms.java | 15 +- .../impl/ProgramMetadataServiceImpl.java | 80 +++---- .../trackedentity/TrackedEntityType.java | 4 +- .../WritableTrackedEntityType.java | 4 +- .../impl/ProgramMetadataServiceImplTest.java | 41 ++-- ...gramMetadataToFhirCarePlanTransformer.java | 72 ++++++ .../fhir/metadata/model/AbstractRule.java | 5 +- .../metadata/model/OrganizationUnitRule.java | 4 - .../repository/CustomRuleRepository.java | 4 + .../OrganizationUnitRuleRepository.java | 2 +- ...tomOrganizationUnitRuleRepositoryImpl.java | 74 ------- .../impl/CustomRuleRepositoryImpl.java | 14 ++ .../repository/impl/DhisRepositoryImpl.java | 4 +- .../impl/PolledProgramRetrieverImpl.java | 4 +- .../dhis/DhisToFhirDataProvider.java | 3 +- .../dhis/DhisToFhirTransformerService.java | 3 +- .../impl/AbstractDhisToFhirDataProvider.java | 11 +- .../AbstractPreparedDhisToFhirSearch.java | 4 +- .../DhisToFhirTransformerServiceImpl.java | 21 +- ...stractDhisMetadataToFhirDataProvider.java} | 78 ++++--- ...ractDhisMetadataToFhirRequestResolver.java | 73 ++++++ ...gramMetadataToFhirCarePlanTransformer.java | 90 ++++++++ ...eadOnlyDhisMetadataToFhirTransformer.java} | 100 ++++----- ...nlyDhisMetadataToTypedFhirTransformer.java | 98 +++++++++ ...ava => DhisMetadataToFhirSearchState.java} | 6 +- ... => PreparedDhisMetadataToFhirSearch.java} | 9 +- .../OrganizationUnitResolver.java | 2 +- .../OrganizationUnitToFhirDataProvider.java | 77 +++++++ ...OrganizationUnitToFhirRequestResolver.java | 33 +-- .../OrganizationUnitToFhirTransformer.java | 132 +++++++++++ .../ProgramMetadataToFhirDataProvider.java | 77 +++++++ .../ProgramMetadataToFhirRequestResolver.java | 72 ++++++ .../PreparedProgramStageToFhirSearch.java | 5 +- .../ProgramStageToFhirDataProvider.java | 9 +- .../ProgramStageToFhirRequestResolver.java | 2 +- .../TrackedEntityToFhirDataProvider.java | 7 + .../program/FhirToEnrollmentTransformer.java | 2 +- .../FhirToProgramStageTransformer.java | 4 +- .../ImmutableScriptedDhisMetadata.java | 135 ++++++++++++ .../scripted/ScriptedDhisMetadata.java} | 26 ++- .../scripted/ScriptedOrganizationUnit.java | 4 +- .../WritableScriptedDhisMetadata.java | 140 ++++++++++++ .../WritableScriptedOrganizationUnit.java | 108 +-------- .../FhirToEnrollmentTransformerTest.java | 2 +- .../FhirToProgramStageTransformerTest.java | 2 +- .../MetadataSheetProgramImportProcessor.java | 2 +- .../MetadataSheetRuleImportProcessor.java | 2 +- 69 files changed, 1768 insertions(+), 671 deletions(-) rename dhis/src/main/java/org/dhis2/fhir/adapter/dhis/model/{AbstractDhisType.java => AbstractDhisMetadata.java} (95%) rename dhis/src/main/java/org/dhis2/fhir/adapter/dhis/model/{DhisType.java => DhisMetadata.java} (90%) create mode 100644 dhis/src/main/java/org/dhis2/fhir/adapter/dhis/service/DhisMetadataService.java create mode 100644 dhis/src/main/java/org/dhis2/fhir/adapter/dhis/service/impl/AbstractDhisMetadataServiceImpl.java create mode 100644 dhis/src/main/java/org/dhis2/fhir/adapter/dhis/service/impl/DhisMetadataItems.java rename dhis/src/main/java/org/dhis2/fhir/adapter/dhis/{orgunit/impl/OrganizationUnitPolledItem.java => service/impl/DhisMetadataPolledItem.java} (89%) create mode 100644 dhis/src/main/java/org/dhis2/fhir/adapter/dhis/service/impl/DhisMetadataPolledItemDeserializer.java rename dhis/src/main/java/org/dhis2/fhir/adapter/dhis/{orgunit/impl/OrganizationUnitPolledItemRetriever.java => service/impl/DhisMetadataPolledItemRetriever.java} (71%) rename dhis/src/main/java/org/dhis2/fhir/adapter/dhis/{orgunit/impl/OrganizationUnitPolledItems.java => service/impl/DhisMetadataPolledItems.java} (72%) create mode 100644 fhir-r4/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/r4/R4ProgramMetadataToFhirCarePlanTransformer.java delete mode 100644 fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/impl/CustomOrganizationUnitRuleRepositoryImpl.java rename fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/{OrganizationUnitToFhirDataProvider.java => AbstractDhisMetadataToFhirDataProvider.java} (63%) create mode 100644 fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/AbstractDhisMetadataToFhirRequestResolver.java create mode 100644 fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/AbstractProgramMetadataToFhirCarePlanTransformer.java rename fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/{OrganizationUnitToFhirTransformer.java => AbstractReadOnlyDhisMetadataToFhirTransformer.java} (62%) create mode 100644 fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/AbstractReadOnlyDhisMetadataToTypedFhirTransformer.java rename fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/{OrganizationUnitToFhirSearchState.java => DhisMetadataToFhirSearchState.java} (89%) rename fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/{PreparedOrganizationUnitDhisToFhirSearch.java => PreparedDhisMetadataToFhirSearch.java} (80%) rename fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/{ => orgunit}/OrganizationUnitResolver.java (99%) create mode 100644 fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/orgunit/OrganizationUnitToFhirDataProvider.java rename fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/{ => orgunit}/OrganizationUnitToFhirRequestResolver.java (72%) create mode 100644 fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/orgunit/OrganizationUnitToFhirTransformer.java create mode 100644 fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/program/ProgramMetadataToFhirDataProvider.java create mode 100644 fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/program/ProgramMetadataToFhirRequestResolver.java create mode 100644 fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/scripted/ImmutableScriptedDhisMetadata.java rename fhir/src/main/java/org/dhis2/fhir/adapter/fhir/{metadata/repository/CustomOrganizationUnitRuleRepository.java => transform/scripted/ScriptedDhisMetadata.java} (72%) create mode 100644 fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/scripted/WritableScriptedDhisMetadata.java diff --git a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/config/DhisMetadataCacheConfig.java b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/config/DhisMetadataCacheConfig.java index 8fe17a25..02e83776 100644 --- a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/config/DhisMetadataCacheConfig.java +++ b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/config/DhisMetadataCacheConfig.java @@ -1,7 +1,7 @@ package org.dhis2.fhir.adapter.dhis.config; /* - * Copyright (c) 2004-2018, University of Oslo + * Copyright (c) 2004-2019, University of Oslo * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,11 +28,16 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +import org.apache.commons.lang3.StringUtils; import org.dhis2.fhir.adapter.cache.AbstractSimpleCacheConfig; import org.dhis2.fhir.adapter.cache.RequestCacheService; import org.springframework.beans.factory.ObjectProvider; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.cache.CacheManager; +import org.springframework.cache.interceptor.AbstractCacheResolver; +import org.springframework.cache.interceptor.CacheOperationInvocationContext; +import org.springframework.cache.interceptor.CacheResolver; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; @@ -42,6 +47,8 @@ import org.springframework.validation.annotation.Validated; import javax.annotation.Nonnull; +import java.util.Collection; +import java.util.Collections; /** * Cache configuration for FHIR Resources. @@ -70,4 +77,27 @@ protected CacheManager dhisCacheManager( @Nonnull RequestCacheService requestCac { return createCacheManager( requestCacheService, redisConnectionFactoryProvider, redisSerializer ); } + + @Nonnull + @Bean + protected CacheResolver dhisMetadataCacheResolver( @Nonnull @Qualifier( "dhisCacheManager" ) CacheManager cacheManager ) + { + return new AbstractCacheResolver( cacheManager ) + { + @Override + protected Collection getCacheNames( @Nonnull CacheOperationInvocationContext context ) + { + String name = context.getTarget().getClass().getSimpleName(); + + final int index = name.indexOf( "Service" ); + + if ( index > 0 ) + { + name = name.substring( 0, index ); + } + + return Collections.singletonList( StringUtils.uncapitalize( name ) ); + } + }; + } } diff --git a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/model/AbstractDhisType.java b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/model/AbstractDhisMetadata.java similarity index 95% rename from dhis/src/main/java/org/dhis2/fhir/adapter/dhis/model/AbstractDhisType.java rename to dhis/src/main/java/org/dhis2/fhir/adapter/dhis/model/AbstractDhisMetadata.java index f849325b..e1114eca 100644 --- a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/model/AbstractDhisType.java +++ b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/model/AbstractDhisMetadata.java @@ -36,11 +36,11 @@ import java.util.Set; /** - * Abstract implementation of {@link DhisType}. + * Abstract implementation of {@link DhisMetadata}. * * @author volsch */ -public abstract class AbstractDhisType implements DhisType, Serializable +public abstract class AbstractDhisMetadata implements DhisMetadata, Serializable { private static final long serialVersionUID = 7960220674294587120L; diff --git a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/model/DataElement.java b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/model/DataElement.java index 547d5c9c..e5262251 100644 --- a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/model/DataElement.java +++ b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/model/DataElement.java @@ -39,7 +39,7 @@ * @author volsch */ @Scriptable -public interface DataElement extends DhisType +public interface DataElement extends DhisMetadata { String getId(); diff --git a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/model/DhisType.java b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/model/DhisMetadata.java similarity index 90% rename from dhis/src/main/java/org/dhis2/fhir/adapter/dhis/model/DhisType.java rename to dhis/src/main/java/org/dhis2/fhir/adapter/dhis/model/DhisMetadata.java index b12513a5..0e2dd4f1 100644 --- a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/model/DhisType.java +++ b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/model/DhisMetadata.java @@ -34,19 +34,19 @@ import java.util.Set; /** - * Implemented by DHIS 2 types. + * Implemented by DHIS 2 metadata. * * @author volsch */ -public interface DhisType extends Identifiable +public interface DhisMetadata extends Identifiable { /** - * @return the unique code of the type or null if the type has no code. + * @return the unique code of the metadata or null if the type has no code. */ String getCode(); /** - * @return the unique name of the type. + * @return the unique name of the metadata. */ String getName(); diff --git a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/model/WritableDataElement.java b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/model/WritableDataElement.java index 0a889702..0dabcc03 100644 --- a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/model/WritableDataElement.java +++ b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/model/WritableDataElement.java @@ -38,7 +38,7 @@ * * @author volsch */ -public class WritableDataElement extends AbstractDhisType implements DataElement, Serializable +public class WritableDataElement extends AbstractDhisMetadata implements DataElement, Serializable { private static final long serialVersionUID = -3933887626350878763L; diff --git a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/orgunit/OrganizationUnit.java b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/orgunit/OrganizationUnit.java index 5f58a83b..01685b55 100644 --- a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/orgunit/OrganizationUnit.java +++ b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/orgunit/OrganizationUnit.java @@ -29,6 +29,8 @@ */ import com.fasterxml.jackson.annotation.JsonIgnore; +import org.dhis2.fhir.adapter.dhis.model.AbstractDhisMetadata; +import org.dhis2.fhir.adapter.dhis.model.DhisMetadata; import org.dhis2.fhir.adapter.dhis.model.DhisResource; import org.dhis2.fhir.adapter.dhis.model.DhisResourceId; import org.dhis2.fhir.adapter.dhis.model.DhisResourceType; @@ -43,7 +45,7 @@ * * @author volsch */ -public class OrganizationUnit implements DhisResource, Serializable +public class OrganizationUnit extends AbstractDhisMetadata implements DhisResource, DhisMetadata, Serializable { private static final long serialVersionUID = 3976508569865955265L; diff --git a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/orgunit/OrganizationUnitService.java b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/orgunit/OrganizationUnitService.java index f4137eef..ae14ee7e 100644 --- a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/orgunit/OrganizationUnitService.java +++ b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/orgunit/OrganizationUnitService.java @@ -28,39 +28,13 @@ * 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.Reference; -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; +import org.dhis2.fhir.adapter.dhis.service.DhisMetadataService; /** * Service that provides access to DHIS2 organization unit metadata. * * @author volsch */ -public interface OrganizationUnitService +public interface OrganizationUnitService extends DhisMetadataService { - @Nonnull - Optional findMetadataByReference( @Nonnull Reference reference ); - - @Nonnull - Optional findMetadataRefreshedByReference( @Nonnull Reference reference ); - - @Nonnull - Optional findOneByReference( @Nonnull Reference reference ); - - @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/orgunit/impl/DhisOrganizationUnits.java b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/orgunit/impl/DhisOrganizationUnits.java index 3c97523b..e089aaf6 100644 --- a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/orgunit/impl/DhisOrganizationUnits.java +++ b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/orgunit/impl/DhisOrganizationUnits.java @@ -29,12 +29,10 @@ */ import com.fasterxml.jackson.annotation.JsonProperty; -import org.dhis2.fhir.adapter.dhis.model.Pager; import org.dhis2.fhir.adapter.dhis.orgunit.OrganizationUnit; +import org.dhis2.fhir.adapter.dhis.service.impl.DhisMetadataItems; -import javax.annotation.Nonnull; import java.io.Serializable; -import java.util.ArrayList; import java.util.List; /** @@ -42,37 +40,18 @@ * * @author volsch */ -public class DhisOrganizationUnits implements Serializable +public class DhisOrganizationUnits extends DhisMetadataItems implements Serializable { private static final long serialVersionUID = -671810199580040339L; - private Pager pager; - @JsonProperty( "organisationUnits" ) - private List organizationUnits; - - public Pager getPager() - { - return pager; - } - - public void setPager( Pager pager ) - { - this.pager = pager; - } - - @Nonnull public List getOrganizationUnits() { - if ( organizationUnits == null ) - { - organizationUnits = new ArrayList<>(); - } - return organizationUnits; + return getItems(); } public void setOrganizationUnits( List organizationUnits ) { - this.organizationUnits = organizationUnits; + setItems( organizationUnits ); } } 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 0c16590a..c0839e5d 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 @@ -28,42 +28,17 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; -import org.dhis2.fhir.adapter.auth.UnauthorizedException; -import org.dhis2.fhir.adapter.data.model.ProcessedItemInfo; -import org.dhis2.fhir.adapter.dhis.DhisFindException; -import org.dhis2.fhir.adapter.dhis.metadata.model.DhisSyncGroup; -import org.dhis2.fhir.adapter.dhis.model.DhisResourceResult; -import org.dhis2.fhir.adapter.dhis.model.Reference; -import org.dhis2.fhir.adapter.dhis.model.UriFilterApplier; +import org.dhis2.fhir.adapter.dhis.model.DhisResourceType; import org.dhis2.fhir.adapter.dhis.orgunit.OrganizationUnit; import org.dhis2.fhir.adapter.dhis.orgunit.OrganizationUnitService; -import org.dhis2.fhir.adapter.dhis.util.DhisPagingQuery; -import org.dhis2.fhir.adapter.dhis.util.DhisPagingUtils; -import org.dhis2.fhir.adapter.rest.RestTemplateUtils; +import org.dhis2.fhir.adapter.dhis.service.impl.AbstractDhisMetadataServiceImpl; +import org.dhis2.fhir.adapter.dhis.service.impl.DhisMetadataItems; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.cache.annotation.CacheConfig; -import org.springframework.cache.annotation.CachePut; -import org.springframework.cache.annotation.Cacheable; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; -import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.RestTemplate; -import org.springframework.web.util.UriComponentsBuilder; import javax.annotation.Nonnull; -import java.time.Instant; -import java.time.ZoneId; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; -import java.util.function.Consumer; /** * Implementation of {@link OrganizationUnitService}. @@ -71,124 +46,41 @@ * @author volsch */ @Service -@CacheConfig( cacheNames = "organizationUnit", cacheManager = "dhisCacheManager" ) -public class OrganizationUnitServiceImpl implements OrganizationUnitService +public class OrganizationUnitServiceImpl extends AbstractDhisMetadataServiceImpl implements OrganizationUnitService { protected static final String FIELDS = "lastUpdated,id,code,name,shortName,displayName,level,openingDate,closedDate,coordinates,leaf,parent[id]"; - protected static final String ORGANIZATION_UNIT_BY_CODE_URI = "/organisationUnits.json?paging=false&fields=" + FIELDS + "&filter=code:eq:{code}"; - - protected static final String ORGANIZATION_UNIT_BY_NAME_URI = "/organisationUnits.json?paging=false&fields=" + FIELDS + "&filter=name:eq:{name}"; - - protected static final String ORGANIZATION_UNIT_BY_ID_URI = "/organisationUnits/{id}.json?fields=" + FIELDS; - - private final RestTemplate systemRestTemplate; - - private final RestTemplate userRestTemplate; - - private final ZoneId zoneId = ZoneId.systemDefault(); - @Autowired public OrganizationUnitServiceImpl( @Nonnull @Qualifier( "systemDhis2RestTemplate" ) RestTemplate systemRestTemplate, @Nonnull @Qualifier( "userDhis2RestTemplate" ) RestTemplate userRestTemplate ) { - this.systemRestTemplate = systemRestTemplate; - this.userRestTemplate = userRestTemplate; + super( systemRestTemplate, userRestTemplate ); } - @Cacheable - @HystrixCommand - @Override @Nonnull - public Optional findMetadataByReference( @Nonnull Reference reference ) - { - return findMetadataRefreshedByReference( reference ); - } - - @HystrixCommand @Override - @Nonnull - @CachePut( unless = "#result==null" ) - public Optional findMetadataRefreshedByReference( @Nonnull Reference reference ) + protected DhisResourceType getDhisResourceType() { - return findByReference( systemRestTemplate, reference ); + return DhisResourceType.ORGANIZATION_UNIT; } - @HystrixCommand( ignoreExceptions = UnauthorizedException.class ) @Nonnull @Override - @CachePut( unless = "#result==null" ) - public Optional findOneByReference( @Nonnull Reference reference ) + protected Class getItemClass() { - return findByReference( userRestTemplate, reference ); + return OrganizationUnit.class; } - @HystrixCommand( ignoreExceptions = UnauthorizedException.class ) @Nonnull @Override - public DhisResourceResult find( @Nonnull UriFilterApplier uriFilterApplier, int from, int max ) - { - final DhisPagingQuery pagingQuery = DhisPagingUtils.createPagingQuery( from, max ); - final List variables = new ArrayList<>(); - final String uri = uriFilterApplier.add( UriComponentsBuilder.newInstance(), variables ).path( "/organisationUnits.json" ) - .queryParam( "paging", "true" ).queryParam( "page", pagingQuery.getPage() ).queryParam( "pageSize", pagingQuery.getPageSize() ) - .queryParam( "order", "id" ).queryParam( "fields", FIELDS ).build( false ).toString(); - - final ResponseEntity result; - try - { - result = userRestTemplate.getForEntity( uri, DhisOrganizationUnits.class, variables.toArray() ); - } - catch ( HttpClientErrorException e ) - { - if ( e.getStatusCode() == HttpStatus.BAD_REQUEST || e.getStatusCode() == HttpStatus.CONFLICT ) - { - throw new DhisFindException( e.getMessage(), e ); - } - throw e; - } - final DhisOrganizationUnits organizationUnits = Objects.requireNonNull( result.getBody() ); - - return new DhisResourceResult<>( (organizationUnits.getOrganizationUnits().size() > pagingQuery.getResultOffset()) ? - organizationUnits.getOrganizationUnits().subList( pagingQuery.getResultOffset(), organizationUnits.getOrganizationUnits().size() ) : Collections.emptyList(), - (organizationUnits.getPager().getNextPage() != null) ); - } - - @Nonnull - protected Optional findByReference( @Nonnull RestTemplate restTemplate, @Nonnull Reference reference ) + protected Class> getItemsClass() { - final ResponseEntity result; - switch ( reference.getType() ) - { - case CODE: - result = restTemplate.getForEntity( ORGANIZATION_UNIT_BY_CODE_URI, DhisOrganizationUnits.class, reference.getValue() ); - break; - case NAME: - result = restTemplate.getForEntity( ORGANIZATION_UNIT_BY_NAME_URI, DhisOrganizationUnits.class, reference.getValue() ); - break; - case ID: - try - { - return Optional.of( Objects.requireNonNull( restTemplate.getForEntity( ORGANIZATION_UNIT_BY_ID_URI, OrganizationUnit.class, reference.getValue() ).getBody() ) ); - } - catch ( HttpClientErrorException e ) - { - if ( RestTemplateUtils.isNotFound( e ) ) - { - return Optional.empty(); - } - throw e; - } - default: - throw new AssertionError( "Unhandled reference type: " + reference.getType() ); - } - return Objects.requireNonNull( result.getBody() ).getOrganizationUnits().stream().findFirst(); + return DhisOrganizationUnits.class; } @Nonnull @Override - public Instant poll( @Nonnull DhisSyncGroup group, @Nonnull Instant lastUpdated, int toleranceMillis, int maxSearchCount, @Nonnull Set excludedStoredBy, @Nonnull Consumer> consumer ) + protected String getFieldNames() { - final OrganizationUnitPolledItemRetriever eventPolledItemRetriever = new OrganizationUnitPolledItemRetriever( systemRestTemplate, toleranceMillis, maxSearchCount, zoneId ); - return eventPolledItemRetriever.poll( lastUpdated, excludedStoredBy, consumer, null ); + return FIELDS; } } diff --git a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/poll/PolledItems.java b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/poll/PolledItems.java index 8d85da06..5edcb87f 100644 --- a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/poll/PolledItems.java +++ b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/poll/PolledItems.java @@ -1,7 +1,7 @@ package org.dhis2.fhir.adapter.dhis.poll; /* - * Copyright (c) 2004-2018, University of Oslo + * Copyright (c) 2004-2019, University of Oslo * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -52,6 +52,7 @@ public class PolledItems implements Serializable private List items; + @JsonProperty public Pager getPager() { return pager; 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 new file mode 100644 index 00000000..e36d5ce3 --- /dev/null +++ b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/service/DhisMetadataService.java @@ -0,0 +1,69 @@ +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.DhisMetadata; +import org.dhis2.fhir.adapter.dhis.model.DhisResource; +import org.dhis2.fhir.adapter.dhis.model.DhisResourceResult; +import org.dhis2.fhir.adapter.dhis.model.Reference; +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. + * + * @param the concrete type of the metadata. + * @author volsch + */ +public interface DhisMetadataService +{ + @Nonnull + Optional findMetadataByReference( @Nonnull Reference reference ); + + @Nonnull + Optional findMetadataRefreshedByReference( @Nonnull Reference reference ); + + @Nonnull + Optional findOneByReference( @Nonnull Reference reference ); + + @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/impl/AbstractDhisMetadataServiceImpl.java b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/service/impl/AbstractDhisMetadataServiceImpl.java new file mode 100644 index 00000000..767102db --- /dev/null +++ b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/service/impl/AbstractDhisMetadataServiceImpl.java @@ -0,0 +1,208 @@ +package org.dhis2.fhir.adapter.dhis.service.impl; + +/* + * 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 com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; +import org.dhis2.fhir.adapter.auth.UnauthorizedException; +import org.dhis2.fhir.adapter.data.model.ProcessedItemInfo; +import org.dhis2.fhir.adapter.dhis.DhisFindException; +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; +import org.dhis2.fhir.adapter.dhis.model.DhisResourceType; +import org.dhis2.fhir.adapter.dhis.model.Reference; +import org.dhis2.fhir.adapter.dhis.model.UriFilterApplier; +import org.dhis2.fhir.adapter.dhis.orgunit.OrganizationUnitService; +import org.dhis2.fhir.adapter.dhis.service.DhisMetadataService; +import org.dhis2.fhir.adapter.dhis.util.DhisPagingQuery; +import org.dhis2.fhir.adapter.dhis.util.DhisPagingUtils; +import org.dhis2.fhir.adapter.rest.RestTemplateUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.cache.annotation.CachePut; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.util.UriComponentsBuilder; + +import javax.annotation.Nonnull; +import java.time.Instant; +import java.time.ZoneId; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.function.Consumer; +import java.util.stream.Collectors; + +/** + * Implementation of {@link OrganizationUnitService}. + * + * @param the concrete type of the metadata. + * @author volsch + */ +@Service +public abstract class AbstractDhisMetadataServiceImpl implements DhisMetadataService +{ + private final RestTemplate systemRestTemplate; + + private final RestTemplate userRestTemplate; + + private final ZoneId zoneId = ZoneId.systemDefault(); + + @Autowired + protected AbstractDhisMetadataServiceImpl( @Nonnull @Qualifier( "systemDhis2RestTemplate" ) RestTemplate systemRestTemplate, @Nonnull @Qualifier( "userDhis2RestTemplate" ) RestTemplate userRestTemplate ) + { + this.systemRestTemplate = systemRestTemplate; + this.userRestTemplate = userRestTemplate; + } + + @Nonnull + protected abstract DhisResourceType getDhisResourceType(); + + @Nonnull + protected abstract Class getItemClass(); + + @Nonnull + protected abstract Class> getItemsClass(); + + @Nonnull + protected abstract String getFieldNames(); + + @Cacheable( cacheResolver = "dhisMetadataCacheResolver" ) + @HystrixCommand + @Override + @Nonnull + public Optional findMetadataByReference( @Nonnull Reference reference ) + { + return findMetadataRefreshedByReference( reference ); + } + + @HystrixCommand + @Override + @Nonnull + @CachePut( cacheResolver = "dhisMetadataCacheResolver", unless = "#result==null" ) + public Optional findMetadataRefreshedByReference( @Nonnull Reference reference ) + { + return findOneByReference( systemRestTemplate, reference ); + } + + @HystrixCommand( ignoreExceptions = UnauthorizedException.class ) + @Nonnull + @Override + @CachePut( cacheResolver = "dhisMetadataCacheResolver", unless = "#result==null" ) + public Optional findOneByReference( @Nonnull Reference reference ) + { + return findOneByReference( userRestTemplate, reference ); + } + + @HystrixCommand( ignoreExceptions = UnauthorizedException.class ) + @Nonnull + @Override + public DhisResourceResult find( @Nonnull UriFilterApplier uriFilterApplier, int from, int max ) + { + final DhisPagingQuery pagingQuery = DhisPagingUtils.createPagingQuery( from, max ); + final List variables = new ArrayList<>(); + final String uri = uriFilterApplier.add( UriComponentsBuilder.newInstance(), variables ).path( "/" + getDhisResourceType().getTypeName() + ".json" ) + .queryParam( "paging", "true" ).queryParam( "page", pagingQuery.getPage() ).queryParam( "pageSize", pagingQuery.getPageSize() ) + .queryParam( "order", "id" ).queryParam( "fields", getFieldNames() ).build( false ).toString(); + + final ResponseEntity> result; + try + { + result = userRestTemplate.getForEntity( uri, getItemsClass(), variables.toArray() ); + } + catch ( HttpClientErrorException e ) + { + if ( e.getStatusCode() == HttpStatus.BAD_REQUEST || e.getStatusCode() == HttpStatus.CONFLICT ) + { + throw new DhisFindException( e.getMessage(), e ); + } + + throw e; + } + + final DhisMetadataItems items = Objects.requireNonNull( result.getBody() ); + + return new DhisResourceResult<>( ( items.getItems().size() > pagingQuery.getResultOffset() ) ? + items.getItems().stream().skip( pagingQuery.getResultOffset() ).map( item -> (T) item ).collect( Collectors.toList() ) : Collections.emptyList(), + ( items.getPager().getNextPage() != null ) ); + } + + @Nonnull + protected Optional findOneByReference( @Nonnull RestTemplate restTemplate, @Nonnull Reference reference ) + { + final ResponseEntity> result; + + switch ( reference.getType() ) + { + case CODE: + result = restTemplate.getForEntity( "/" + getDhisResourceType().getTypeName() + ".json?paging=false&fields=" + getFieldNames() + "&filter=code:eq:{code}", getItemsClass(), reference.getValue() ); + break; + case NAME: + result = restTemplate.getForEntity( "/" + getDhisResourceType().getTypeName() + ".json?paging=false&fields=" + getFieldNames() + "&filter=name:eq:{name}", getItemsClass(), reference.getValue() ); + break; + case ID: + try + { + return Optional.of( Objects.requireNonNull( restTemplate.getForEntity( "/" + getDhisResourceType().getTypeName() + "/{id}.json?fields=" + getFieldNames(), getItemClass(), reference.getValue() ).getBody() ) ); + } + catch ( HttpClientErrorException e ) + { + if ( RestTemplateUtils.isNotFound( e ) ) + { + return Optional.empty(); + } + + throw e; + } + default: + throw new AssertionError( "Unhandled reference type: " + reference.getType() ); + } + + return Objects.requireNonNull( result.getBody() ).getItems().stream().map( item -> (T) item ).findFirst(); + } + + @Nonnull + @Override + public Instant poll( @Nonnull DhisSyncGroup group, @Nonnull Instant lastUpdated, int toleranceMillis, int maxSearchCount, @Nonnull Set excludedStoredBy, @Nonnull Consumer> consumer ) + { + final DhisMetadataPolledItemRetriever eventPolledItemRetriever = new DhisMetadataPolledItemRetriever( getDhisResourceType(), systemRestTemplate, + toleranceMillis, maxSearchCount, zoneId ); + + return eventPolledItemRetriever.poll( lastUpdated, excludedStoredBy, consumer, null ); + } +} diff --git a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/service/impl/DhisMetadataItems.java b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/service/impl/DhisMetadataItems.java new file mode 100644 index 00000000..677ee787 --- /dev/null +++ b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/service/impl/DhisMetadataItems.java @@ -0,0 +1,82 @@ +package org.dhis2.fhir.adapter.dhis.service.impl; + +/* + * 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 com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import org.dhis2.fhir.adapter.dhis.model.DhisMetadata; +import org.dhis2.fhir.adapter.dhis.model.Pager; + +import javax.annotation.Nonnull; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * Container object used for DHIS2 metadata items. + * + * @param the concrete type of the metadata. + * @author volsch + */ +public class DhisMetadataItems implements Serializable +{ + private static final long serialVersionUID = -671810199580040339L; + + private Pager pager; + + private List items; + + @JsonProperty + public Pager getPager() + { + return pager; + } + + public void setPager( Pager pager ) + { + this.pager = pager; + } + + @JsonIgnore + @Nonnull + public List getItems() + { + if ( items == null ) + { + items = new ArrayList<>(); + } + + return items; + } + + public void setItems( List items ) + { + this.items = items; + } +} diff --git a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/orgunit/impl/OrganizationUnitPolledItem.java b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/service/impl/DhisMetadataPolledItem.java similarity index 89% rename from dhis/src/main/java/org/dhis2/fhir/adapter/dhis/orgunit/impl/OrganizationUnitPolledItem.java rename to dhis/src/main/java/org/dhis2/fhir/adapter/dhis/service/impl/DhisMetadataPolledItem.java index 0a049462..fca3a032 100644 --- a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/orgunit/impl/OrganizationUnitPolledItem.java +++ b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/service/impl/DhisMetadataPolledItem.java @@ -1,7 +1,7 @@ -package org.dhis2.fhir.adapter.dhis.orgunit.impl; +package org.dhis2.fhir.adapter.dhis.service.impl; /* - * Copyright (c) 2004-2018, University of Oslo + * Copyright (c) 2004-2019, University of Oslo * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,11 +31,11 @@ import org.dhis2.fhir.adapter.dhis.poll.PolledItem; /** - * The polled items of an organization units. + * The polled items of a DHIS 2 metadata. * * @author volsch */ -public class OrganizationUnitPolledItem extends PolledItem +public class DhisMetadataPolledItem extends PolledItem { private static final long serialVersionUID = 1293380714892822351L; } diff --git a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/service/impl/DhisMetadataPolledItemDeserializer.java b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/service/impl/DhisMetadataPolledItemDeserializer.java new file mode 100644 index 00000000..01126e98 --- /dev/null +++ b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/service/impl/DhisMetadataPolledItemDeserializer.java @@ -0,0 +1,77 @@ +package org.dhis2.fhir.adapter.dhis.service.impl; + +/* + * 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 com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.fasterxml.jackson.databind.node.ObjectNode; + +import java.io.IOException; +import java.util.Iterator; + +/** + * Deserializer for polled items. The first returned array field will be taken + * as list of polled items. + * + * @author volsch + */ +public class DhisMetadataPolledItemDeserializer extends StdDeserializer +{ + private static final long serialVersionUID = -7632523079641260663L; + + public DhisMetadataPolledItemDeserializer() + { + super( DhisMetadataPolledItems.class ); + } + + @Override + public DhisMetadataPolledItems deserialize( JsonParser p, DeserializationContext ctxt ) throws IOException + { + final ObjectNode rootNode = p.getCodec().readTree( p ); + + for ( final Iterator iterator = rootNode.fieldNames(); iterator.hasNext(); ) + { + final String fieldName = iterator.next(); + final JsonNode fieldNode = rootNode.get( fieldName ); + + if ( fieldNode.isArray() ) + { + // rename field to items + rootNode.remove( fieldName ); + rootNode.set( "items", fieldNode ); + + break; + } + } + + return p.getCodec().treeToValue( rootNode, DhisMetadataPolledItems.class ); + } +} diff --git a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/orgunit/impl/OrganizationUnitPolledItemRetriever.java b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/service/impl/DhisMetadataPolledItemRetriever.java similarity index 71% rename from dhis/src/main/java/org/dhis2/fhir/adapter/dhis/orgunit/impl/OrganizationUnitPolledItemRetriever.java rename to dhis/src/main/java/org/dhis2/fhir/adapter/dhis/service/impl/DhisMetadataPolledItemRetriever.java index 9c7865ef..982d6679 100644 --- a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/orgunit/impl/OrganizationUnitPolledItemRetriever.java +++ b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/service/impl/DhisMetadataPolledItemRetriever.java @@ -1,7 +1,7 @@ -package org.dhis2.fhir.adapter.dhis.orgunit.impl; +package org.dhis2.fhir.adapter.dhis.service.impl; /* - * Copyright (c) 2004-2018, University of Oslo + * Copyright (c) 2004-2019, University of Oslo * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -45,26 +45,27 @@ * * @author volsch */ -public class OrganizationUnitPolledItemRetriever extends AbstractPolledItemRetriever +public class DhisMetadataPolledItemRetriever extends AbstractPolledItemRetriever { - protected static final String POLL_URI = "/organisationUnits.json?fields=id,lastUpdated"; - - public OrganizationUnitPolledItemRetriever( @Nonnull RestTemplate restTemplate, int toleranceMillis, int maxSearchCount, @Nonnull ZoneId zoneId ) + public DhisMetadataPolledItemRetriever( @Nonnull DhisResourceType dhisResourceType, @Nonnull RestTemplate restTemplate, int toleranceMillis, int maxSearchCount, @Nonnull ZoneId zoneId ) { - super( DhisResourceType.ORGANIZATION_UNIT, restTemplate, POLL_URI, toleranceMillis, maxSearchCount, OrganizationUnitPolledItems.class, zoneId ); + super( dhisResourceType, restTemplate, "/" + dhisResourceType.getTypeName() + ".json?fields=id,lastUpdated", toleranceMillis, + maxSearchCount, DhisMetadataPolledItems.class, zoneId ); } @Nonnull @Override - protected OrganizationUnitPolledItems getPolledItems( @Nonnull Instant fromLastUpdated, @Nullable Instant currentToLastUpdated, int page, @Nullable List variables ) + protected DhisMetadataPolledItems getPolledItems( @Nonnull Instant fromLastUpdated, @Nullable Instant currentToLastUpdated, int page, @Nullable List variables ) { - final OrganizationUnitPolledItems polledItems = super.getPolledItems( fromLastUpdated, currentToLastUpdated, page, variables ); + final DhisMetadataPolledItems polledItems = super.getPolledItems( fromLastUpdated, currentToLastUpdated, page, variables ); + if ( polledItems.getItems().isEmpty() ) { return polledItems; } + final LocalDateTime localFromLastUpdated = fromLastUpdated.atZone( getZoneId() ).toLocalDateTime(); - return new OrganizationUnitPolledItems( polledItems.getItems().stream() + return new DhisMetadataPolledItems( polledItems.getItems().stream() .filter( i -> !localFromLastUpdated.isAfter( i.getLastUpdated() ) ).collect( Collectors.toList() ) ); } diff --git a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/orgunit/impl/OrganizationUnitPolledItems.java b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/service/impl/DhisMetadataPolledItems.java similarity index 72% rename from dhis/src/main/java/org/dhis2/fhir/adapter/dhis/orgunit/impl/OrganizationUnitPolledItems.java rename to dhis/src/main/java/org/dhis2/fhir/adapter/dhis/service/impl/DhisMetadataPolledItems.java index 10c07552..cb22ffde 100644 --- a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/orgunit/impl/OrganizationUnitPolledItems.java +++ b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/service/impl/DhisMetadataPolledItems.java @@ -1,7 +1,7 @@ -package org.dhis2.fhir.adapter.dhis.orgunit.impl; +package org.dhis2.fhir.adapter.dhis.service.impl; /* - * Copyright (c) 2004-2018, University of Oslo + * Copyright (c) 2004-2019, University of Oslo * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,41 +28,29 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import org.dhis2.fhir.adapter.dhis.poll.PolledItems; import javax.annotation.Nonnull; import java.util.List; /** - * Polled items for organization units. + * Polled items for DHIS 2 metadata. * * @author volsch */ -public class OrganizationUnitPolledItems extends PolledItems +@JsonDeserialize( using = DhisMetadataPolledItemDeserializer.class ) +public class DhisMetadataPolledItems extends PolledItems { private static final long serialVersionUID = -3139366174834526658L; - public OrganizationUnitPolledItems() + public DhisMetadataPolledItems() { super(); } - public OrganizationUnitPolledItems( @Nonnull List items ) + public DhisMetadataPolledItems( @Nonnull List items ) { setItems( items ); } - - @JsonProperty( "organisationUnits" ) - @Override - public List getItems() - { - return super.getItems(); - } - - @Override - public void setItems( List items ) - { - super.setItems( items ); - } } diff --git a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/Program.java b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/Program.java index 853f0f57..27e79901 100644 --- a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/Program.java +++ b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/Program.java @@ -28,8 +28,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +import org.dhis2.fhir.adapter.dhis.model.DhisMetadata; import org.dhis2.fhir.adapter.dhis.model.DhisResource; -import org.dhis2.fhir.adapter.dhis.model.DhisType; import org.dhis2.fhir.adapter.dhis.model.Reference; import org.dhis2.fhir.adapter.scriptable.Scriptable; @@ -46,7 +46,7 @@ * @author volsch */ @Scriptable -public interface Program extends DhisResource, DhisType +public interface Program extends DhisResource, DhisMetadata { String getTrackedEntityTypeId(); diff --git a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/ProgramMetadataService.java b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/ProgramMetadataService.java index 29d6c62f..dae5cfd6 100644 --- a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/ProgramMetadataService.java +++ b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/ProgramMetadataService.java @@ -1,7 +1,7 @@ package org.dhis2.fhir.adapter.dhis.tracker.program; /* - * Copyright (c) 2004-2018, University of Oslo + * Copyright (c) 2004-2019, University of Oslo * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,13 +28,13 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import org.dhis2.fhir.adapter.dhis.model.Reference; +import org.dhis2.fhir.adapter.dhis.service.DhisMetadataService; -import javax.annotation.Nonnull; -import java.util.Optional; - -public interface ProgramMetadataService +/** + * Metadata service for DHIS2 programs. + * + * @author volsch + */ +public interface ProgramMetadataService extends DhisMetadataService { - @Nonnull - Optional findProgramByReference( @Nonnull Reference reference ); } diff --git a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/ProgramStage.java b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/ProgramStage.java index b6c271b1..de69ff15 100644 --- a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/ProgramStage.java +++ b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/ProgramStage.java @@ -28,8 +28,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +import org.dhis2.fhir.adapter.dhis.model.DhisMetadata; import org.dhis2.fhir.adapter.dhis.model.DhisResource; -import org.dhis2.fhir.adapter.dhis.model.DhisType; import org.dhis2.fhir.adapter.dhis.model.Reference; import org.dhis2.fhir.adapter.scriptable.Scriptable; @@ -46,7 +46,7 @@ * @author volsch */ @Scriptable -public interface ProgramStage extends DhisResource, DhisType +public interface ProgramStage extends DhisResource, DhisMetadata { boolean isRepeatable(); 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 23887763..bf7ac0cd 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 @@ -31,7 +31,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import org.dhis2.fhir.adapter.dhis.model.AbstractDhisType; +import org.dhis2.fhir.adapter.dhis.model.AbstractDhisMetadata; import org.dhis2.fhir.adapter.dhis.model.DhisResourceId; import org.dhis2.fhir.adapter.dhis.model.DhisResourceType; import org.dhis2.fhir.adapter.dhis.model.Reference; @@ -46,7 +46,7 @@ import java.util.Optional; import java.util.stream.Collectors; -public class WritableProgram extends AbstractDhisType implements Program, Serializable +public class WritableProgram extends AbstractDhisMetadata implements Program, Serializable { private static final long serialVersionUID = -4906529875383953995L; diff --git a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/WritableProgramStage.java b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/WritableProgramStage.java index c5e44835..31efc464 100644 --- a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/WritableProgramStage.java +++ b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/WritableProgramStage.java @@ -30,7 +30,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; -import org.dhis2.fhir.adapter.dhis.model.AbstractDhisType; +import org.dhis2.fhir.adapter.dhis.model.AbstractDhisMetadata; import org.dhis2.fhir.adapter.dhis.model.DhisResourceId; import org.dhis2.fhir.adapter.dhis.model.DhisResourceType; import org.dhis2.fhir.adapter.dhis.model.Reference; @@ -44,7 +44,7 @@ import java.util.Optional; import java.util.stream.Collectors; -public class WritableProgramStage extends AbstractDhisType implements ProgramStage, Serializable +public class WritableProgramStage extends AbstractDhisMetadata implements ProgramStage, Serializable { private static final long serialVersionUID = -7544648580734783374L; diff --git a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/impl/DhisPrograms.java b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/impl/DhisPrograms.java index 972b1dc7..38cf2a0c 100644 --- a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/impl/DhisPrograms.java +++ b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/impl/DhisPrograms.java @@ -1,7 +1,7 @@ package org.dhis2.fhir.adapter.dhis.tracker.program.impl; /* - * Copyright (c) 2004-2018, University of Oslo + * Copyright (c) 2004-2019, University of Oslo * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,6 +28,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +import com.fasterxml.jackson.annotation.JsonProperty; +import org.dhis2.fhir.adapter.dhis.service.impl.DhisMetadataItems; import org.dhis2.fhir.adapter.dhis.tracker.program.WritableProgram; import java.io.Serializable; @@ -38,24 +40,23 @@ * * @author volsch */ -public class DhisPrograms implements Serializable +public class DhisPrograms extends DhisMetadataItems implements Serializable { private static final long serialVersionUID = 1084527285362478422L; - private List programs; - + @JsonProperty( "programs" ) public List getPrograms() { - return programs; + return getItems(); } public void setPrograms( List programs ) { - this.programs = programs; + setItems( programs ); } public List toModel() { - return programs; + return getItems(); } } 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 83458545..f0f5cb9a 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 @@ -1,7 +1,7 @@ package org.dhis2.fhir.adapter.dhis.tracker.program.impl; /* - * Copyright (c) 2004-2018, University of Oslo + * Copyright (c) 2004-2019, University of Oslo * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,25 +28,17 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; -import org.dhis2.fhir.adapter.dhis.model.Reference; -import org.dhis2.fhir.adapter.dhis.tracker.program.ImmutableProgram; +import org.dhis2.fhir.adapter.dhis.model.DhisResourceType; +import org.dhis2.fhir.adapter.dhis.service.impl.AbstractDhisMetadataServiceImpl; +import org.dhis2.fhir.adapter.dhis.service.impl.DhisMetadataItems; import org.dhis2.fhir.adapter.dhis.tracker.program.Program; import org.dhis2.fhir.adapter.dhis.tracker.program.ProgramMetadataService; import org.dhis2.fhir.adapter.dhis.tracker.program.WritableProgram; -import org.dhis2.fhir.adapter.rest.RestTemplateUtils; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.cache.annotation.CacheConfig; -import org.springframework.cache.annotation.Cacheable; -import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; -import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.RestTemplate; import javax.annotation.Nonnull; -import java.util.Objects; -import java.util.Optional; /** * Implementation of a {@link ProgramMetadataService}. @@ -54,8 +46,7 @@ * @author volsch */ @Service -@CacheConfig( cacheNames = "programMetadata", cacheManager = "dhisCacheManager" ) -public class ProgramMetadataServiceImpl implements ProgramMetadataService +public class ProgramMetadataServiceImpl extends AbstractDhisMetadataServiceImpl implements ProgramMetadataService { protected static final String FIELDS = "id,name,code,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate," + @@ -66,53 +57,36 @@ public class ProgramMetadataServiceImpl implements ProgramMetadataService "programStageDataElements[id,compulsory,allowProvidedElsewhere," + "dataElement[id,name,code,formName,valueType,optionSetValue,optionSet[id,name,options[code,name]]]]]"; - protected static final String PROGRAM_BY_CODE_URI = "/programs.json?paging=false&fields=" + FIELDS + "&filter=code:eq:{code}"; - - protected static final String PROGRAM_BY_NAME_URI = "/programs.json?paging=false&fields=" + FIELDS + "&filter=name:eq:{name}"; + public ProgramMetadataServiceImpl( @Nonnull @Qualifier( "systemDhis2RestTemplate" ) RestTemplate systemRestTemplate, @Nonnull @Qualifier( "userDhis2RestTemplate" ) RestTemplate userRestTemplate ) + { + super( systemRestTemplate, userRestTemplate ); + } - protected static final String PROGRAM_BY_ID_URI = "/programs/{id}.json?fields=" + FIELDS; + @Nonnull + @Override + protected DhisResourceType getDhisResourceType() + { + return DhisResourceType.PROGRAM_METADATA; + } - private final RestTemplate restTemplate; + @Nonnull + @Override + protected Class getItemClass() + { + return WritableProgram.class; + } - @Autowired - public ProgramMetadataServiceImpl( @Nonnull @Qualifier( "systemDhis2RestTemplate" ) RestTemplate restTemplate ) + @Nonnull + @Override + protected Class> getItemsClass() { - this.restTemplate = restTemplate; + return DhisPrograms.class; } - @HystrixCommand - @Cacheable @Nonnull @Override - public Optional findProgramByReference( @Nonnull Reference reference ) + protected String getFieldNames() { - final ResponseEntity result; - switch ( reference.getType() ) - { - case CODE: - result = restTemplate.getForEntity( PROGRAM_BY_CODE_URI, DhisPrograms.class, reference.getValue() ); - break; - case NAME: - result = restTemplate.getForEntity( PROGRAM_BY_NAME_URI, DhisPrograms.class, reference.getValue() ); - break; - case ID: - try - { - return Optional.of( Objects.requireNonNull( restTemplate.getForEntity( - PROGRAM_BY_ID_URI, WritableProgram.class, reference.getValue() ).getBody() ) ) - .map( ImmutableProgram::new ); - } - catch ( HttpClientErrorException e ) - { - if ( RestTemplateUtils.isNotFound( e ) ) - { - return Optional.empty(); - } - throw e; - } - default: - throw new AssertionError( "Unhandled reference type: " + reference.getType() ); - } - return Objects.requireNonNull( result.getBody() ).getPrograms().stream().map( ImmutableProgram::new ).findFirst(); + return FIELDS; } } diff --git a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/trackedentity/TrackedEntityType.java b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/trackedentity/TrackedEntityType.java index a1722d35..5eb8b3ca 100644 --- a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/trackedentity/TrackedEntityType.java +++ b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/trackedentity/TrackedEntityType.java @@ -28,7 +28,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import org.dhis2.fhir.adapter.dhis.model.DhisType; +import org.dhis2.fhir.adapter.dhis.model.DhisMetadata; import org.dhis2.fhir.adapter.dhis.model.ItemContainerType; import org.dhis2.fhir.adapter.dhis.model.Reference; import org.dhis2.fhir.adapter.scriptable.Scriptable; @@ -39,7 +39,7 @@ import java.util.Optional; @Scriptable -public interface TrackedEntityType extends DhisType, ItemContainerType +public interface TrackedEntityType extends DhisMetadata, ItemContainerType { List getAttributes(); diff --git a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/trackedentity/WritableTrackedEntityType.java b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/trackedentity/WritableTrackedEntityType.java index f0d83698..a546c24c 100644 --- a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/trackedentity/WritableTrackedEntityType.java +++ b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/trackedentity/WritableTrackedEntityType.java @@ -31,7 +31,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import org.apache.commons.lang3.StringUtils; -import org.dhis2.fhir.adapter.dhis.model.AbstractDhisType; +import org.dhis2.fhir.adapter.dhis.model.AbstractDhisMetadata; import org.dhis2.fhir.adapter.dhis.model.Reference; import javax.annotation.Nonnull; @@ -42,7 +42,7 @@ import java.util.Optional; import java.util.stream.Collectors; -public class WritableTrackedEntityType extends AbstractDhisType implements TrackedEntityType, Serializable +public class WritableTrackedEntityType extends AbstractDhisMetadata implements TrackedEntityType, Serializable { private static final long serialVersionUID = 797154293863611491L; 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 a4d95fea..abd1ec9f 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 @@ -1,7 +1,7 @@ package org.dhis2.fhir.adapter.dhis.tracker.program.impl; /* - * Copyright (c) 2004-2018, University of Oslo + * Copyright (c) 2004-2019, University of Oslo * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -61,7 +61,9 @@ */ public class ProgramMetadataServiceImplTest { - private RestTemplate restTemplate; + private RestTemplate systemRestTemplate; + + private RestTemplate userRestTemplate; private MockRestServiceServer mockServer; @@ -70,48 +72,49 @@ public class ProgramMetadataServiceImplTest @Before public void setUp() { - restTemplate = new RestTemplateBuilder().rootUri( "http://localhost:8080/api" ).build(); - mockServer = MockRestServiceServer.createServer( restTemplate ); - service = new ProgramMetadataServiceImpl( restTemplate ); + systemRestTemplate = new RestTemplateBuilder().rootUri( "http://localhost:8080/api" ).build(); + userRestTemplate = new RestTemplateBuilder().rootUri( "http://localhost:8080/api" ).build(); + mockServer = MockRestServiceServer.createServer( systemRestTemplate ); + service = new ProgramMetadataServiceImpl( systemRestTemplate, userRestTemplate ); } @Test - public void findOneByReferenceId() throws IOException + public void findMetadataByReferenceId() throws IOException { mockServer.expect( requestTo( "http://localhost:8080/api/programs/93783.json?fields=id,name,code,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,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 ) ); - Optional ou = service.findProgramByReference( new Reference( "93783", ReferenceType.ID ) ); + Optional ou = service.findMetadataByReference( new Reference( "93783", ReferenceType.ID ) ); Assert.assertTrue( ou.isPresent() ); assertProgram( ou.get() ); } @Test - public void findOneByReferenceIdNotFound() + public void findMetadataByReferenceIdNotFound() { mockServer.expect( requestTo( "http://localhost:8080/api/programs/93783.json?fields=id,name,code,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,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 ) ); - Optional ou = service.findProgramByReference( new Reference( "93783", ReferenceType.ID ) ); + Optional ou = service.findMetadataByReference( new Reference( "93783", ReferenceType.ID ) ); Assert.assertFalse( ou.isPresent() ); } @Test( expected = HttpServerErrorException.class ) - public void findOneByReferenceIdServerError() + public void findMetadataByReferenceIdServerError() { mockServer.expect( requestTo( "http://localhost:8080/api/programs/93783.json?fields=id,name,code,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,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() ); - service.findProgramByReference( new Reference( "93783", ReferenceType.ID ) ); + service.findMetadataByReference( new Reference( "93783", ReferenceType.ID ) ); } @Test - public void findOneByReferenceCode() throws IOException + public void findMetadataByReferenceCode() throws IOException { mockServer.expect( requestTo( "http://localhost:8080/api/programs.json?paging=false&fields=id,name,code,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,repeatable,captureCoordinates," + @@ -119,13 +122,13 @@ public void findOneByReferenceCode() throws IOException "name%5D%5D%5D%5D%5D&filter=code:eq:OU_3783" ) ).andExpect( method( HttpMethod.GET ) ) .andRespond( withSuccess( IOUtils.resourceToByteArray( "/org/dhis2/fhir/adapter/dhis/tracker/program/impl/programs.json" ), MediaType.APPLICATION_JSON ) ); - Optional ou = service.findProgramByReference( new Reference( "OU_3783", ReferenceType.CODE ) ); + Optional ou = service.findMetadataByReference( new Reference( "OU_3783", ReferenceType.CODE ) ); Assert.assertTrue( ou.isPresent() ); assertProgram( ou.get() ); } @Test - public void findOneByReferenceCodeNotFound() throws IOException + public void findMetadataByReferenceCodeNotFound() throws IOException { mockServer.expect( requestTo( "http://localhost:8080/api/programs.json?paging=false&fields=id,name,code,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,repeatable,captureCoordinates," + @@ -133,12 +136,12 @@ public void findOneByReferenceCodeNotFound() throws IOException "name%5D%5D%5D%5D%5D&filter=code:eq:OU_3783" ) ).andExpect( method( HttpMethod.GET ) ) .andRespond( withSuccess( IOUtils.resourceToByteArray( "/org/dhis2/fhir/adapter/dhis/tracker/program/impl/emptyPrograms.json" ), MediaType.APPLICATION_JSON ) ); - Optional ou = service.findProgramByReference( new Reference( "OU_3783", ReferenceType.CODE ) ); + Optional ou = service.findMetadataByReference( new Reference( "OU_3783", ReferenceType.CODE ) ); Assert.assertFalse( ou.isPresent() ); } @Test - public void findOneByReferenceName() throws IOException + public void findMetadataByReferenceName() throws IOException { mockServer.expect( requestTo( "http://localhost:8080/api/programs.json?paging=false&fields=id,name,code,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,repeatable,captureCoordinates," + @@ -146,13 +149,13 @@ public void findOneByReferenceName() throws IOException "name%5D%5D%5D%5D%5D&filter=name:eq:Freetown" ) ).andExpect( method( HttpMethod.GET ) ) .andRespond( withSuccess( IOUtils.resourceToByteArray( "/org/dhis2/fhir/adapter/dhis/tracker/program/impl/programs.json" ), MediaType.APPLICATION_JSON ) ); - Optional ou = service.findProgramByReference( new Reference( "Freetown", ReferenceType.NAME ) ); + Optional ou = service.findMetadataByReference( new Reference( "Freetown", ReferenceType.NAME ) ); Assert.assertTrue( ou.isPresent() ); assertProgram( ou.get() ); } @Test - public void findOneByReferenceNameNotFound() throws IOException + public void findMetadataByReferenceNameNotFound() throws IOException { mockServer.expect( requestTo( "http://localhost:8080/api/programs.json?paging=false&fields=id,name,code,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,repeatable,captureCoordinates," + @@ -160,7 +163,7 @@ public void findOneByReferenceNameNotFound() throws IOException "name%5D%5D%5D%5D%5D&filter=name:eq:Freetown" ) ).andExpect( method( HttpMethod.GET ) ) .andRespond( withSuccess( IOUtils.resourceToByteArray( "/org/dhis2/fhir/adapter/dhis/tracker/program/impl/emptyPrograms.json" ), MediaType.APPLICATION_JSON ) ); - Optional ou = service.findProgramByReference( new Reference( "Freetown", ReferenceType.NAME ) ); + Optional ou = service.findMetadataByReference( new Reference( "Freetown", ReferenceType.NAME ) ); Assert.assertFalse( ou.isPresent() ); } diff --git a/fhir-r4/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/r4/R4ProgramMetadataToFhirCarePlanTransformer.java b/fhir-r4/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/r4/R4ProgramMetadataToFhirCarePlanTransformer.java new file mode 100644 index 00000000..2869b0c6 --- /dev/null +++ b/fhir-r4/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/r4/R4ProgramMetadataToFhirCarePlanTransformer.java @@ -0,0 +1,72 @@ +package org.dhis2.fhir.adapter.fhir.transform.dhis.impl.metadata.r4; + +/* + * 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.orgunit.OrganizationUnitService; +import org.dhis2.fhir.adapter.dhis.tracker.program.ProgramMetadataService; +import org.dhis2.fhir.adapter.fhir.data.repository.FhirDhisAssignmentRepository; +import org.dhis2.fhir.adapter.fhir.metadata.model.FhirResourceType; +import org.dhis2.fhir.adapter.fhir.metadata.repository.SystemRepository; +import org.dhis2.fhir.adapter.fhir.model.FhirVersion; +import org.dhis2.fhir.adapter.fhir.repository.FhirResourceRepository; +import org.dhis2.fhir.adapter.fhir.script.ScriptExecutor; +import org.dhis2.fhir.adapter.fhir.transform.dhis.impl.metadata.AbstractProgramMetadataToFhirCarePlanTransformer; +import org.dhis2.fhir.adapter.lock.LockManager; +import org.hl7.fhir.r4.model.PlanDefinition; + +import javax.annotation.Nonnull; +import java.util.Set; + +/** + * R4 specific version of DHIS 2 Program Metadata to FHIR Plan Definition transformer. + * + * @author volsch + */ +public class R4ProgramMetadataToFhirCarePlanTransformer extends AbstractProgramMetadataToFhirCarePlanTransformer +{ + public R4ProgramMetadataToFhirCarePlanTransformer( @Nonnull ScriptExecutor scriptExecutor, @Nonnull LockManager lockManager, @Nonnull SystemRepository systemRepository, @Nonnull FhirResourceRepository fhirResourceRepository, + @Nonnull FhirDhisAssignmentRepository fhirDhisAssignmentRepository, @Nonnull OrganizationUnitService organizationUnitService, @Nonnull ProgramMetadataService programMetadataService ) + { + super( scriptExecutor, lockManager, systemRepository, fhirResourceRepository, fhirDhisAssignmentRepository, organizationUnitService, programMetadataService ); + } + + @Nonnull + @Override + public Set getFhirVersions() + { + return FhirVersion.R4_ONLY; + } + + @Nonnull + @Override + protected FhirResourceType getFhirResourceType() + { + return FhirResourceType.PLAN_DEFINITION; + } +} diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/AbstractRule.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/AbstractRule.java index 14e64cc8..b5bf83f7 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/AbstractRule.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/AbstractRule.java @@ -98,7 +98,8 @@ "SELECT r FROM AbstractRule r JOIN r.applicableCodeSet acs WHERE r.fhirResourceType=:fhirResourceType AND r.enabled=true " + "AND r.expEnabled=true AND acs.code IN (:codeSetCodes)" ), @NamedQuery( name = AbstractRule.FIND_IMP_RULE_BY_ID_NAMED_QUERY, query = - "SELECT r FROM AbstractRule r WHERE r.fhirResourceType=:fhirResourceType AND TYPE(r)=:dhisResourceType AND r.id=:ruleId AND r.enabled=true AND r.impEnabled=true" ) + "SELECT r FROM AbstractRule r WHERE r.fhirResourceType=:fhirResourceType AND TYPE(r)=:dhisResourceType AND r.id=:ruleId AND r.enabled=true AND r.impEnabled=true" ), + @NamedQuery( name = AbstractRule.FIND_ALL_EXP_NAMED_QUERY, query = "SELECT our FROM OrganizationUnitRule our WHERE our.enabled=true AND our.expEnabled=true AND (our.fhirCreateEnabled=true OR our.fhirUpdateEnabled=true)" ) } ) @JsonTypeInfo( use = JsonTypeInfo.Id.NAME, property = "dhisResourceType", include = JsonTypeInfo.As.EXISTING_PROPERTY ) @JsonSubTypes( { @@ -128,6 +129,8 @@ public abstract class AbstractRule extends VersionedBaseMetadata implements Seri public static final String FIND_IMP_RULE_BY_ID_NAMED_QUERY = "AbstractRule.findImpById"; + public static final String FIND_ALL_EXP_NAMED_QUERY = "AbstractRule.findAllExp"; + public static final int MAX_NAME_LENGTH = 230; @NotBlank diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/OrganizationUnitRule.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/OrganizationUnitRule.java index 7f67a2eb..7fd2141e 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/OrganizationUnitRule.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/OrganizationUnitRule.java @@ -37,7 +37,6 @@ import javax.persistence.Entity; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; -import javax.persistence.NamedQuery; import javax.persistence.Table; /** @@ -48,14 +47,11 @@ @Entity @Table( name = "fhir_organization_unit_rule" ) @DiscriminatorValue( "ORGANIZATION_UNIT" ) -@NamedQuery( name = OrganizationUnitRule.FIND_ALL_EXP_NAMED_QUERY, query = "SELECT our FROM OrganizationUnitRule our WHERE our.enabled=true AND our.expEnabled=true AND (our.fhirCreateEnabled=true OR our.fhirUpdateEnabled=true)" ) @JsonFilter( value = AdapterBeanPropertyFilter.FILTER_NAME ) public class OrganizationUnitRule extends AbstractSimpleRule { private static final long serialVersionUID = -3997570895838354307L; - public static final String FIND_ALL_EXP_NAMED_QUERY = "OrganizationUnitRule.findAllExp"; - private ExecutableScript identifierLookupScript; private ExecutableScript managingOrgIdentifierLookupScript; diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/CustomRuleRepository.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/CustomRuleRepository.java index ad3ff033..fcd443a4 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/CustomRuleRepository.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/CustomRuleRepository.java @@ -65,4 +65,8 @@ public interface CustomRuleRepository @Nonnull Optional> findOneExpByDhisFhirInputData( @Nonnull FhirResourceType fhirResourceType ); + @RestResource( exported = false ) + @Nonnull + Collection> findAllExp(); + } diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/OrganizationUnitRuleRepository.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/OrganizationUnitRuleRepository.java index 706c2ac7..093c3b9c 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/OrganizationUnitRuleRepository.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/OrganizationUnitRuleRepository.java @@ -50,7 +50,7 @@ @CacheConfig( cacheManager = "metadataCacheManager", cacheNames = "rule" ) @RepositoryRestResource @PreAuthorize( "hasRole('DATA_MAPPING')" ) -public interface OrganizationUnitRuleRepository extends JpaRepository, QuerydslPredicateExecutor, CustomOrganizationUnitRuleRepository, MetadataRepository +public interface OrganizationUnitRuleRepository extends JpaRepository, QuerydslPredicateExecutor, MetadataRepository { @Nonnull @Override diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/impl/CustomOrganizationUnitRuleRepositoryImpl.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/impl/CustomOrganizationUnitRuleRepositoryImpl.java deleted file mode 100644 index d8524033..00000000 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/impl/CustomOrganizationUnitRuleRepositoryImpl.java +++ /dev/null @@ -1,74 +0,0 @@ -package org.dhis2.fhir.adapter.fhir.metadata.repository.impl; - -/* - * 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. - */ - -import org.dhis2.fhir.adapter.fhir.metadata.model.OrganizationUnitRule; -import org.dhis2.fhir.adapter.fhir.metadata.model.RuleInfo; -import org.dhis2.fhir.adapter.fhir.metadata.repository.CustomOrganizationUnitRuleRepository; -import org.hibernate.Hibernate; -import org.springframework.cache.annotation.CacheConfig; -import org.springframework.cache.annotation.Cacheable; -import org.springframework.data.rest.core.annotation.RestResource; -import org.springframework.transaction.annotation.Transactional; - -import javax.annotation.Nonnull; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import java.util.Collection; -import java.util.List; -import java.util.stream.Collectors; - -/** - * Implementation of {@link CustomOrganizationUnitRuleRepository}. - */ -@CacheConfig( cacheManager = "metadataCacheManager", cacheNames = "rule" ) -public class CustomOrganizationUnitRuleRepositoryImpl implements CustomOrganizationUnitRuleRepository -{ - @PersistenceContext - private EntityManager entityManager; - - public CustomOrganizationUnitRuleRepositoryImpl( @Nonnull EntityManager entityManager ) - { - this.entityManager = entityManager; - } - - @RestResource( exported = false ) - @Nonnull - @Cacheable( key = "{#root.methodName}" ) - @Transactional( readOnly = true ) - public Collection> findAllExp() - { - final List rules = entityManager.createNamedQuery( - OrganizationUnitRule.FIND_ALL_EXP_NAMED_QUERY, OrganizationUnitRule.class ).getResultList(); - return rules.stream().map( r -> { - Hibernate.initialize( r.getDhisDataReferences() ); - return new RuleInfo<>( r, r.getDhisDataReferences() ); - } ).collect( Collectors.toList() ); - } -} diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/impl/CustomRuleRepositoryImpl.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/impl/CustomRuleRepositoryImpl.java index e3f460e9..5305b436 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/impl/CustomRuleRepositoryImpl.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/impl/CustomRuleRepositoryImpl.java @@ -109,6 +109,20 @@ public List> findAllExpByInputData( @Nonnull Fh AbstractRule.FIND_EXP_RULES_BY_FHIR_TYPE_CODES_NAMED_QUERY, AbstractRule.FIND_EXP_RULES_BY_FHIR_TYPE_CODE_SETS_NAMED_QUERY ); } + @RestResource( exported = false ) + @Nonnull + @Cacheable( key = "{#root.methodName}", cacheManager = "metadataCacheManager", cacheNames = "rule" ) + @Transactional( readOnly = true ) + public Collection> findAllExp() + { + final List rules = entityManager.createNamedQuery( AbstractRule.FIND_ALL_EXP_NAMED_QUERY, AbstractRule.class ).getResultList(); + + return rules.stream().map( r -> { + Hibernate.initialize( r.getDhisDataReferences() ); + return new RuleInfo<>( r, r.getDhisDataReferences() ); + } ).collect( Collectors.toList() ); + } + @Nonnull protected List> findAllByInputData( @Nonnull FhirResourceType fhirResourceType, @Nullable Collection systemCodeValues, @Nonnull String findByFhirTypeQueryName, @Nonnull String findBySystemCodeQueryName, @Nonnull String findByCodeSetCodeQueryName ) diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/repository/impl/DhisRepositoryImpl.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/repository/impl/DhisRepositoryImpl.java index a1554c05..c9f0936c 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/repository/impl/DhisRepositoryImpl.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/repository/impl/DhisRepositoryImpl.java @@ -246,7 +246,7 @@ protected DhisToFhirTransformerRequest createTransformerRequest( @Nonnull FhirRe @Override protected DhisResource getDhisResource() { - return dhisToFhirTransformerService.getDataProvider( ruleInfo.getRule().getDhisResourceType() ) + return dhisToFhirTransformerService.getDataProvider( fhirClient.getFhirVersion(), ruleInfo.getRule().getDhisResourceType() ) .findByDhisFhirIdentifierCasted( fhirClient, ruleInfo, identifier ); } }.read( fhirClient, fhirResourceType ); @@ -304,7 +304,7 @@ protected List search( @Nonnull FhirClient fhirClient, @Nonnull F return Collections.emptyList(); } - final DhisToFhirDataProvider dataProvider = dhisToFhirTransformerService.getDataProvider( dhisResourceType ); + final DhisToFhirDataProvider dataProvider = dhisToFhirTransformerService.getDataProvider( fhirClient.getFhirVersion(), dhisResourceType ); final PreparedDhisToFhirSearch preparedSearch = dataProvider.prepareSearchCasted( fhirClient.getFhirVersion(), rules, filter, lastUpdatedDateRange, count ); final LinkedList dhisResources = new LinkedList<>(); diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/repository/impl/PolledProgramRetrieverImpl.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/repository/impl/PolledProgramRetrieverImpl.java index 6e27744c..6c50b450 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/repository/impl/PolledProgramRetrieverImpl.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/repository/impl/PolledProgramRetrieverImpl.java @@ -1,7 +1,7 @@ package org.dhis2.fhir.adapter.fhir.repository.impl; /* - * Copyright (c) 2004-2018, University of Oslo + * Copyright (c) 2004-2019, University of Oslo * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -68,7 +68,7 @@ public Collection findAllPolledProgramIds() final Set ids = new HashSet<>(); for ( final Reference ref : mappedTrackerProgramRepository.findAllPolledProgramReferences() ) { - programMetadataService.findProgramByReference( ref ).ifPresent( p -> ids.add( p.getId() ) ); + programMetadataService.findMetadataByReference( ref ).ifPresent( p -> ids.add( p.getId() ) ); } return ids; } diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/DhisToFhirDataProvider.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/DhisToFhirDataProvider.java index 7b4e53df..debdd24a 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/DhisToFhirDataProvider.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/DhisToFhirDataProvider.java @@ -35,6 +35,7 @@ import org.dhis2.fhir.adapter.fhir.metadata.model.FhirClient; import org.dhis2.fhir.adapter.fhir.metadata.model.RuleInfo; import org.dhis2.fhir.adapter.fhir.model.FhirVersion; +import org.dhis2.fhir.adapter.fhir.model.FhirVersionRestricted; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -47,7 +48,7 @@ * @param the concrete type of the rule. * @author volsch */ -public interface DhisToFhirDataProvider +public interface DhisToFhirDataProvider extends FhirVersionRestricted { @Nonnull DhisResourceType getDhisResourceType(); diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/DhisToFhirTransformerService.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/DhisToFhirTransformerService.java index 8853eab5..aa6e3917 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/DhisToFhirTransformerService.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/DhisToFhirTransformerService.java @@ -34,6 +34,7 @@ import org.dhis2.fhir.adapter.fhir.metadata.model.FhirClient; import org.dhis2.fhir.adapter.fhir.metadata.model.FhirResourceType; import org.dhis2.fhir.adapter.fhir.metadata.model.RuleInfo; +import org.dhis2.fhir.adapter.fhir.model.FhirVersion; import org.dhis2.fhir.adapter.fhir.model.SystemCodeValue; import org.dhis2.fhir.adapter.fhir.transform.TransformerException; import org.dhis2.fhir.adapter.fhir.transform.dhis.model.DhisRequest; @@ -53,7 +54,7 @@ public interface DhisToFhirTransformerService { @Nonnull - DhisToFhirDataProvider getDataProvider( @Nonnull DhisResourceType dhisResourceType ); + DhisToFhirDataProvider getDataProvider( @Nonnull FhirVersion fhirVersion, @Nonnull DhisResourceType dhisResourceType ); @Nullable RuleInfo findSingleRule( @Nonnull FhirClient fhirClient, @Nonnull FhirResourceType fhirResourceType ); diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/AbstractDhisToFhirDataProvider.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/AbstractDhisToFhirDataProvider.java index e394dba4..131d5c26 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/AbstractDhisToFhirDataProvider.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/AbstractDhisToFhirDataProvider.java @@ -76,8 +76,11 @@ protected SearchFilterCollector apply( @Nonnull FhirVersion fhirVersion, @Nonnul ruleInfos.forEach( ruleInfo -> { if ( ruleInfo.getRule().getFilterScript() != null ) { + final SearchFilter searchFilter = new SearchFilter( searchFilterCollector, onlyStringContains ); + initSearchFilter( fhirVersion, ruleInfo, searchFilter ); + final Boolean result = scriptExecutor.execute( ruleInfo.getRule().getFilterScript(), fhirVersion, - Collections.singletonMap( ScriptVariable.SEARCH_FILTER.getVariableName(), new SearchFilter( searchFilterCollector, onlyStringContains ) ), + Collections.singletonMap( ScriptVariable.SEARCH_FILTER.getVariableName(), searchFilter ), Collections.emptyMap(), Boolean.class ); if ( !Boolean.TRUE.equals( result ) ) @@ -86,9 +89,15 @@ protected SearchFilterCollector apply( @Nonnull FhirVersion fhirVersion, @Nonnul } } } ); + return searchFilterCollector; } + protected void initSearchFilter( @Nonnull FhirVersion fhirVersion, @Nonnull RuleInfo ruleInfo, @Nonnull SearchFilter searchFilter ) + { + // method may be overridden + } + @Nullable @Override public DhisResource findByDhisFhirIdentifierCasted( @Nonnull FhirClient fhirClient, @Nonnull RuleInfo ruleInfo, @Nonnull String identifier ) diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/AbstractPreparedDhisToFhirSearch.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/AbstractPreparedDhisToFhirSearch.java index 78bdd651..4b9968ad 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/AbstractPreparedDhisToFhirSearch.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/AbstractPreparedDhisToFhirSearch.java @@ -116,10 +116,12 @@ public U add( @Nonnull U uriBuilder, @Nonnull List requestResolvers = new HashMap<>(); - private final Map> dataProviders = new HashMap<>(); + private final Map>> dataProviders = new HashMap<>(); private final Map, DhisToFhirTransformer> transformers = new HashMap<>(); @@ -158,7 +158,15 @@ public DhisToFhirTransformerServiceImpl( @Nonnull LockManager lockManager, requestResolvers.ifAvailable( resolvers -> resolvers.forEach( r -> this.requestResolvers.put( r.getDhisResourceType(), r ) ) ); dataProviders.ifAvailable( providers -> - providers.forEach( dp -> this.dataProviders.put( dp.getDhisResourceType(), dp ) ) ); + { + for ( final DhisToFhirDataProvider dataProvider : providers ) + { + for ( final FhirVersion fhirVersion : dataProvider.getFhirVersions() ) + { + this.dataProviders.computeIfAbsent( fhirVersion, key -> new HashMap<>() ).put( dataProvider.getDhisResourceType(), dataProvider ); + } + } + } ); transformersProvider.ifAvailable( transformers -> { for ( final DhisToFhirTransformer transformer : transformers ) @@ -183,13 +191,16 @@ public DhisToFhirTransformerServiceImpl( @Nonnull LockManager lockManager, @Nonnull @Override - public DhisToFhirDataProvider getDataProvider( @Nonnull DhisResourceType dhisResourceType ) + public DhisToFhirDataProvider getDataProvider( @Nonnull FhirVersion fhirVersion, @Nonnull DhisResourceType dhisResourceType ) { - final DhisToFhirDataProvider dataProvider = dataProviders.get( dhisResourceType ); + final DhisToFhirDataProvider dataProvider = + dataProviders.computeIfAbsent( fhirVersion, version -> new HashMap<>() ).get( dhisResourceType ); + if ( dataProvider == null ) { - throw new TransformerMappingException( "No data provider can be found for DHIS resource type " + dhisResourceType ); + throw new TransformerMappingException( "No data provider can be found for FHIR version " + fhirVersion + " and DHIS resource type " + dhisResourceType ); } + return dataProvider; } diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/OrganizationUnitToFhirDataProvider.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/AbstractDhisMetadataToFhirDataProvider.java similarity index 63% rename from fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/OrganizationUnitToFhirDataProvider.java rename to fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/AbstractDhisMetadataToFhirDataProvider.java index 5d1be475..30a363b1 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/OrganizationUnitToFhirDataProvider.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/AbstractDhisMetadataToFhirDataProvider.java @@ -30,15 +30,15 @@ import ca.uhn.fhir.rest.param.DateRangeParam; import org.dhis2.fhir.adapter.dhis.DhisFindException; +import org.dhis2.fhir.adapter.dhis.model.DhisMetadata; import org.dhis2.fhir.adapter.dhis.model.DhisResource; import org.dhis2.fhir.adapter.dhis.model.DhisResourceResult; -import org.dhis2.fhir.adapter.dhis.model.DhisResourceType; import org.dhis2.fhir.adapter.dhis.model.Reference; import org.dhis2.fhir.adapter.dhis.model.ReferenceType; -import org.dhis2.fhir.adapter.dhis.orgunit.OrganizationUnit; -import org.dhis2.fhir.adapter.dhis.orgunit.OrganizationUnitService; +import org.dhis2.fhir.adapter.dhis.model.UriFilterApplier; +import org.dhis2.fhir.adapter.dhis.service.DhisMetadataService; +import org.dhis2.fhir.adapter.fhir.metadata.model.AbstractRule; import org.dhis2.fhir.adapter.fhir.metadata.model.FhirClient; -import org.dhis2.fhir.adapter.fhir.metadata.model.OrganizationUnitRule; import org.dhis2.fhir.adapter.fhir.metadata.model.RuleInfo; import org.dhis2.fhir.adapter.fhir.model.FhirVersion; import org.dhis2.fhir.adapter.fhir.script.ScriptExecutor; @@ -48,7 +48,6 @@ import org.dhis2.fhir.adapter.fhir.transform.dhis.DhisToFhirSearchState; import org.dhis2.fhir.adapter.fhir.transform.dhis.PreparedDhisToFhirSearch; import org.dhis2.fhir.adapter.fhir.transform.dhis.impl.AbstractDhisToFhirDataProvider; -import org.springframework.stereotype.Component; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -56,78 +55,75 @@ import java.util.Map; /** - * Implementation of {@link DhisToFhirDataProvider} for DHIS2 Organisation Units. + * Implementation of {@link DhisToFhirDataProvider} for DHIS2 metadata resources. * + * @param the concrete type of the DHIS 2 resource. + * @param the concrete type of the rule that performs the transformation. * @author volsch */ -@Component -public class OrganizationUnitToFhirDataProvider extends AbstractDhisToFhirDataProvider +public abstract class AbstractDhisMetadataToFhirDataProvider extends AbstractDhisToFhirDataProvider { - private final OrganizationUnitService organizationUnitService; + private final DhisMetadataService metadataService; - public OrganizationUnitToFhirDataProvider( @Nonnull ScriptExecutor scriptExecutor, @Nonnull OrganizationUnitService organizationUnitService ) + public AbstractDhisMetadataToFhirDataProvider( @Nonnull ScriptExecutor scriptExecutor, @Nonnull DhisMetadataService metadataService ) { super( scriptExecutor, false ); - this.organizationUnitService = organizationUnitService; + this.metadataService = metadataService; } @Nonnull @Override - public DhisResourceType getDhisResourceType() + public PreparedDhisToFhirSearch prepareSearch( @Nonnull FhirVersion fhirVersion, @Nonnull List> ruleInfos, @Nullable Map> filter, @Nullable DateRangeParam lastUpdatedDateRange, int count ) throws DhisToFhirDataProviderException { - return DhisResourceType.ORGANIZATION_UNIT; - } - - @Nonnull - @Override - protected Class getRuleClass() - { - return OrganizationUnitRule.class; - } - - @Nullable - @Override - public DhisResource findByDhisFhirIdentifier( @Nonnull FhirClient fhirClient, @Nonnull RuleInfo ruleInfo, @Nonnull String identifier ) - { - return organizationUnitService.findOneByReference( new Reference( identifier, ReferenceType.CODE ) ).orElse( null ); - } - - @Nonnull - @Override - public PreparedDhisToFhirSearch prepareSearch( @Nonnull FhirVersion fhirVersion, @Nonnull List> ruleInfos, @Nullable Map> filter, @Nullable DateRangeParam lastUpdatedDateRange, int count ) throws DhisToFhirDataProviderException - { - final PreparedOrganizationUnitDhisToFhirSearch ps = new PreparedOrganizationUnitDhisToFhirSearch( fhirVersion, ruleInfos, filter, lastUpdatedDateRange, count ); + final PreparedDhisMetadataToFhirSearch ps = new PreparedDhisMetadataToFhirSearch<>( fhirVersion, ruleInfos, filter, lastUpdatedDateRange, count ); ps.setUriFilterApplier( apply( fhirVersion, ruleInfos, ps.createSearchFilterCollector( null ) ) ); + return ps; } @Nullable @Override - public DhisToFhirSearchResult search( @Nonnull PreparedDhisToFhirSearch preparedSearch, @Nullable DhisToFhirSearchState state, int max ) + public DhisToFhirSearchResult search( @Nonnull PreparedDhisToFhirSearch preparedSearch, @Nullable DhisToFhirSearchState state, int max ) { - final PreparedOrganizationUnitDhisToFhirSearch ps = (PreparedOrganizationUnitDhisToFhirSearch) preparedSearch; - final OrganizationUnitToFhirSearchState ss = (OrganizationUnitToFhirSearchState) state; + final PreparedDhisMetadataToFhirSearch ps = (PreparedDhisMetadataToFhirSearch) preparedSearch; + final DhisMetadataToFhirSearchState ss = (DhisMetadataToFhirSearchState) state; + if ( (ss != null) && !ss.isMore() ) { return null; } final int from = (ss == null) ? 0 : ss.getFrom(); - final DhisResourceResult result; + final DhisResourceResult result; + try { - result = organizationUnitService.find( ps, from, max ); + result = find( ps, from, max ); } catch ( DhisFindException e ) { throw new DhisToFhirDataProviderException( e.getMessage(), e ); } + if ( result.getResources().isEmpty() ) { return null; } - return new DhisToFhirSearchResult<>( result.getResources(), - new OrganizationUnitToFhirSearchState( from + result.getResources().size(), + + return new DhisToFhirSearchResult<>( result.getResources(), new DhisMetadataToFhirSearchState( from + result.getResources().size(), !result.getResources().isEmpty() && result.isMore() ) ); } + + @Nullable + @Override + public DhisResource findByDhisFhirIdentifier( @Nonnull FhirClient fhirClient, @Nonnull RuleInfo ruleInfo, @Nonnull String identifier ) + { + return metadataService.findOneByReference( new Reference( identifier, ReferenceType.CODE ) ).orElse( null ); + } + + @Nonnull + protected DhisResourceResult find( @Nonnull UriFilterApplier uriFilterApplier, int from, int max ) + { + return metadataService.find( uriFilterApplier, from, max ); + } } diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/AbstractDhisMetadataToFhirRequestResolver.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/AbstractDhisMetadataToFhirRequestResolver.java new file mode 100644 index 00000000..97782994 --- /dev/null +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/AbstractDhisMetadataToFhirRequestResolver.java @@ -0,0 +1,73 @@ +package org.dhis2.fhir.adapter.fhir.transform.dhis.impl.metadata; + +/* + * 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.fhir.metadata.model.AbstractRule; +import org.dhis2.fhir.adapter.fhir.metadata.model.RuleInfo; +import org.dhis2.fhir.adapter.fhir.metadata.repository.FhirClientRepository; +import org.dhis2.fhir.adapter.fhir.metadata.repository.RuleRepository; +import org.dhis2.fhir.adapter.fhir.transform.dhis.impl.AbstractDhisToFhirRequestResolver; +import org.dhis2.fhir.adapter.fhir.transform.dhis.impl.DhisToFhirRequestResolver; +import org.dhis2.fhir.adapter.fhir.transform.scripted.ScriptedDhisResource; +import org.springframework.stereotype.Component; + +import javax.annotation.Nonnull; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Implementation of {@link DhisToFhirRequestResolver} for organization units. + * + * @author volsch + */ +@Component +public abstract class AbstractDhisMetadataToFhirRequestResolver extends AbstractDhisToFhirRequestResolver +{ + private final RuleRepository ruleRepository; + + protected AbstractDhisMetadataToFhirRequestResolver( @Nonnull FhirClientRepository fhirClientRepository, @Nonnull RuleRepository ruleRepository ) + { + super( fhirClientRepository ); + this.ruleRepository = ruleRepository; + } + + @Nonnull + @Override + public List> resolveRules( @Nonnull ScriptedDhisResource dhisResource ) + { + return ruleRepository.findAllExp().stream().sorted().collect( Collectors.toList() ); + } + + @Nonnull + @Override + public List> resolveRules( @Nonnull ScriptedDhisResource dhisResource, @Nonnull List> rules ) + { + return rules.stream().sorted().collect( Collectors.toList() ); + } +} diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/AbstractProgramMetadataToFhirCarePlanTransformer.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/AbstractProgramMetadataToFhirCarePlanTransformer.java new file mode 100644 index 00000000..4ec531e3 --- /dev/null +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/AbstractProgramMetadataToFhirCarePlanTransformer.java @@ -0,0 +1,90 @@ +package org.dhis2.fhir.adapter.fhir.transform.dhis.impl.metadata; + +/* + * 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.DhisResourceType; +import org.dhis2.fhir.adapter.dhis.orgunit.OrganizationUnitService; +import org.dhis2.fhir.adapter.dhis.tracker.program.ProgramMetadataService; +import org.dhis2.fhir.adapter.fhir.data.repository.FhirDhisAssignmentRepository; +import org.dhis2.fhir.adapter.fhir.metadata.model.ProgramMetadataRule; +import org.dhis2.fhir.adapter.fhir.metadata.repository.SystemRepository; +import org.dhis2.fhir.adapter.fhir.repository.FhirResourceRepository; +import org.dhis2.fhir.adapter.fhir.script.ScriptExecutor; +import org.dhis2.fhir.adapter.fhir.transform.dhis.impl.DhisToFhirTransformer; +import org.dhis2.fhir.adapter.fhir.transform.scripted.ScriptedDhisMetadata; +import org.dhis2.fhir.adapter.lock.LockManager; +import org.hl7.fhir.instance.model.api.IBaseResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.annotation.Nonnull; + +/** + * Implementation of {@link DhisToFhirTransformer} for transforming DHIS 2 + * program metadata to FHIR Plan Definition. + * + * @param the concrete type of the FHIR resource into which the DHIS 2 resource should be transformed. + * @author volsch + */ +public abstract class AbstractProgramMetadataToFhirCarePlanTransformer extends AbstractReadOnlyDhisMetadataToTypedFhirTransformer +{ + private final Logger logger = LoggerFactory.getLogger( getClass() ); + + private final ProgramMetadataService programMetadataService; + + public AbstractProgramMetadataToFhirCarePlanTransformer( @Nonnull ScriptExecutor scriptExecutor, @Nonnull LockManager lockManager, @Nonnull SystemRepository systemRepository, @Nonnull FhirResourceRepository fhirResourceRepository, + @Nonnull FhirDhisAssignmentRepository fhirDhisAssignmentRepository, @Nonnull OrganizationUnitService organizationUnitService, @Nonnull ProgramMetadataService programMetadataService ) + { + super( scriptExecutor, lockManager, systemRepository, fhirResourceRepository, fhirDhisAssignmentRepository ); + this.programMetadataService = programMetadataService; + } + + @Nonnull + @Override + public DhisResourceType getDhisResourceType() + { + return DhisResourceType.PROGRAM_METADATA; + } + + @Nonnull + @Override + public Class getDhisResourceClass() + { + return ScriptedDhisMetadata.class; + } + + @Nonnull + @Override + public Class getRuleClass() + { + return ProgramMetadataRule.class; + } + + +} diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/OrganizationUnitToFhirTransformer.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/AbstractReadOnlyDhisMetadataToFhirTransformer.java similarity index 62% rename from fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/OrganizationUnitToFhirTransformer.java rename to fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/AbstractReadOnlyDhisMetadataToFhirTransformer.java index 0359da14..98dc19e0 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/OrganizationUnitToFhirTransformer.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/AbstractReadOnlyDhisMetadataToFhirTransformer.java @@ -28,16 +28,13 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import org.dhis2.fhir.adapter.dhis.model.DhisResourceType; -import org.dhis2.fhir.adapter.dhis.orgunit.OrganizationUnitService; import org.dhis2.fhir.adapter.fhir.data.repository.FhirDhisAssignmentRepository; +import org.dhis2.fhir.adapter.fhir.metadata.model.AbstractRule; import org.dhis2.fhir.adapter.fhir.metadata.model.ExecutableScript; import org.dhis2.fhir.adapter.fhir.metadata.model.FhirClient; -import org.dhis2.fhir.adapter.fhir.metadata.model.OrganizationUnitRule; import org.dhis2.fhir.adapter.fhir.metadata.model.RuleInfo; import org.dhis2.fhir.adapter.fhir.metadata.model.ScriptVariable; import org.dhis2.fhir.adapter.fhir.metadata.repository.SystemRepository; -import org.dhis2.fhir.adapter.fhir.model.FhirVersion; import org.dhis2.fhir.adapter.fhir.repository.FhirResourceRepository; import org.dhis2.fhir.adapter.fhir.script.ScriptExecutor; import org.dhis2.fhir.adapter.fhir.transform.FatalTransformerException; @@ -46,90 +43,61 @@ import org.dhis2.fhir.adapter.fhir.transform.dhis.DhisToFhirTransformerContext; import org.dhis2.fhir.adapter.fhir.transform.dhis.impl.AbstractDhisToFhirTransformer; import org.dhis2.fhir.adapter.fhir.transform.dhis.impl.DhisToFhirTransformer; -import org.dhis2.fhir.adapter.fhir.transform.scripted.ScriptedOrganizationUnit; +import org.dhis2.fhir.adapter.fhir.transform.scripted.ScriptedDhisMetadata; import org.dhis2.fhir.adapter.fhir.transform.util.TransformerUtils; import org.dhis2.fhir.adapter.lock.LockManager; import org.hl7.fhir.instance.model.api.IBaseResource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.HashMap; import java.util.Map; import java.util.Optional; -import java.util.Set; /** - * Implementation of {@link DhisToFhirTransformer} for transforming DHIS 2 - * organization unit to FHIR resources. + * Abstract Implementation of {@link DhisToFhirTransformer} for transforming DHIS 2 + * read-only metadata to FHIR resource. * + * @param the concrete type of the DHIS 2 resource that is processed by this transformer. + * @param the concrete type of the transformer rule that is processed by this transformer. * @author volsch */ -@Component -public class OrganizationUnitToFhirTransformer extends AbstractDhisToFhirTransformer +public abstract class AbstractReadOnlyDhisMetadataToFhirTransformer extends AbstractDhisToFhirTransformer { private final Logger logger = LoggerFactory.getLogger( getClass() ); - private final OrganizationUnitService organizationUnitService; - - public OrganizationUnitToFhirTransformer( @Nonnull ScriptExecutor scriptExecutor, @Nonnull LockManager lockManager, @Nonnull SystemRepository systemRepository, @Nonnull FhirResourceRepository fhirResourceRepository, - @Nonnull FhirDhisAssignmentRepository fhirDhisAssignmentRepository, @Nonnull OrganizationUnitService organizationUnitService ) + protected AbstractReadOnlyDhisMetadataToFhirTransformer( @Nonnull ScriptExecutor scriptExecutor, @Nonnull LockManager lockManager, @Nonnull SystemRepository systemRepository, @Nonnull FhirResourceRepository fhirResourceRepository, + @Nonnull FhirDhisAssignmentRepository fhirDhisAssignmentRepository ) { super( scriptExecutor, lockManager, systemRepository, fhirResourceRepository, fhirDhisAssignmentRepository ); - this.organizationUnitService = organizationUnitService; - } - - @Nonnull - @Override - public Set getFhirVersions() - { - return FhirVersion.ALL; - } - - @Nonnull - @Override - public DhisResourceType getDhisResourceType() - { - return DhisResourceType.ORGANIZATION_UNIT; - } - - @Nonnull - @Override - public Class getDhisResourceClass() - { - return ScriptedOrganizationUnit.class; - } - - @Nonnull - @Override - public Class getRuleClass() - { - return OrganizationUnitRule.class; } @Nullable @Override - public DhisToFhirTransformOutcome transform( @Nonnull FhirClient fhirClient, @Nonnull DhisToFhirTransformerContext context, @Nonnull ScriptedOrganizationUnit input, - @Nonnull RuleInfo ruleInfo, @Nonnull Map scriptVariables ) throws TransformerException + public DhisToFhirTransformOutcome transform( @Nonnull FhirClient fhirClient, @Nonnull DhisToFhirTransformerContext context, @Nonnull R input, @Nonnull RuleInfo ruleInfo, @Nonnull Map scriptVariables ) throws TransformerException { final Map variables = new HashMap<>( scriptVariables ); - variables.put( ScriptVariable.ORGANIZATION_UNIT_RESOLVER.getVariableName(), new OrganizationUnitResolver( - organizationUnitService, getFhirResourceRepository(), fhirClient, context, ruleInfo, variables, - new DefaultIdentifierValueProvider() ) ); + addAdditionalVariables( fhirClient, context, ruleInfo, variables ); final IBaseResource resource = getResource( fhirClient, context, ruleInfo, variables ).orElse( null ); + if ( resource == null ) { return null; } + final IBaseResource modifiedResource = cloneToModified( context, ruleInfo, resource, variables ); + if ( modifiedResource == null ) { return null; } + variables.put( ScriptVariable.OUTPUT.getVariableName(), modifiedResource ); + transform( fhirClient, context, ruleInfo, scriptVariables, input, modifiedResource ); + if ( !transform( context, ruleInfo, variables ) ) { return null; @@ -140,40 +108,48 @@ organizationUnitService, getFhirResourceRepository(), fhirClient, context, ruleI // resource has not been changed and do not need to be updated return new DhisToFhirTransformOutcome<>( ruleInfo.getRule(), null ); } + return new DhisToFhirTransformOutcome<>( ruleInfo.getRule(), modifiedResource ); } + protected void addAdditionalVariables( @Nonnull FhirClient fhirClient, @Nonnull DhisToFhirTransformerContext context, @Nonnull RuleInfo ruleInfo, @Nonnull Map variables ) + { + // method can be overridden + } + + protected void transform( @Nonnull FhirClient fhirClient, @Nonnull DhisToFhirTransformerContext context, @Nonnull RuleInfo ruleInfo, @Nonnull Map scriptVariables, @Nonnull R input, @Nonnull IBaseResource output ) + { + // method can be overridden + } + @Nonnull @Override - protected Optional getActiveResource( @Nonnull FhirClient fhirClient, @Nonnull DhisToFhirTransformerContext context, - @Nonnull RuleInfo ruleInfo, @Nonnull Map scriptVariables ) throws TransformerException + protected Optional getActiveResource( @Nonnull FhirClient fhirClient, @Nonnull DhisToFhirTransformerContext context, @Nonnull RuleInfo ruleInfo, @Nonnull Map scriptVariables ) throws TransformerException { - // not supported return Optional.empty(); } @Override - protected void lockResource( @Nonnull FhirClient fhirClient, @Nonnull DhisToFhirTransformerContext context, - @Nonnull RuleInfo ruleInfo, @Nonnull Map scriptVariables ) throws TransformerException + protected void lockResource( @Nonnull FhirClient fhirClient, @Nonnull DhisToFhirTransformerContext context, @Nonnull RuleInfo rule, @Nonnull Map scriptVariables ) throws TransformerException { if ( !context.getDhisRequest().isDhisFhirId() ) { - final ScriptedOrganizationUnit scriptedOrganizationUnit = - TransformerUtils.getScriptVariable( scriptVariables, ScriptVariable.INPUT, ScriptedOrganizationUnit.class ); + final ScriptedDhisMetadata scriptedMetadata = + TransformerUtils.getScriptVariable( scriptVariables, ScriptVariable.INPUT, ScriptedDhisMetadata.class ); getLockManager().getCurrentLockContext().orElseThrow( () -> new FatalTransformerException( "No lock context available." ) ) - .lock( "out-ou:" + scriptedOrganizationUnit.getId() ); + .lock( "out-" + scriptedMetadata.getResourceType() + ":" + scriptedMetadata.getId() ); } } - @Override @Nullable - protected String getIdentifierValue( @Nonnull DhisToFhirTransformerContext context, @Nonnull RuleInfo ruleInfo, @Nullable ExecutableScript identifierLookupScript, @Nonnull ScriptedOrganizationUnit scriptedOrganizationUnit, - @Nonnull Map scriptVariables ) + @Override + protected String getIdentifierValue( @Nonnull DhisToFhirTransformerContext context, @Nonnull RuleInfo ruleInfo, @Nullable ExecutableScript identifierLookupScript, @Nonnull R scriptedDhisResource, @Nonnull Map scriptVariables ) { if ( context.getDhisRequest().isDhisFhirId() ) { - return scriptedOrganizationUnit.getCode(); + return scriptedDhisResource.getCode(); } - return executeScript( context, ruleInfo, (identifierLookupScript == null) ? ruleInfo.getRule().getIdentifierLookupScript() : identifierLookupScript, scriptVariables, String.class ); + + return executeScript( context, ruleInfo, identifierLookupScript, scriptVariables, String.class ); } } diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/AbstractReadOnlyDhisMetadataToTypedFhirTransformer.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/AbstractReadOnlyDhisMetadataToTypedFhirTransformer.java new file mode 100644 index 00000000..18d80d1a --- /dev/null +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/AbstractReadOnlyDhisMetadataToTypedFhirTransformer.java @@ -0,0 +1,98 @@ +package org.dhis2.fhir.adapter.fhir.transform.dhis.impl.metadata; + +/* + * 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.fhir.data.repository.FhirDhisAssignmentRepository; +import org.dhis2.fhir.adapter.fhir.metadata.model.AbstractRule; +import org.dhis2.fhir.adapter.fhir.metadata.model.FhirClient; +import org.dhis2.fhir.adapter.fhir.metadata.model.FhirResourceType; +import org.dhis2.fhir.adapter.fhir.metadata.model.RuleInfo; +import org.dhis2.fhir.adapter.fhir.metadata.repository.SystemRepository; +import org.dhis2.fhir.adapter.fhir.repository.FhirResourceRepository; +import org.dhis2.fhir.adapter.fhir.script.ScriptExecutor; +import org.dhis2.fhir.adapter.fhir.transform.TransformerException; +import org.dhis2.fhir.adapter.fhir.transform.dhis.DhisToFhirTransformOutcome; +import org.dhis2.fhir.adapter.fhir.transform.dhis.DhisToFhirTransformerContext; +import org.dhis2.fhir.adapter.fhir.transform.dhis.impl.DhisToFhirTransformer; +import org.dhis2.fhir.adapter.fhir.transform.scripted.ScriptedDhisMetadata; +import org.dhis2.fhir.adapter.lock.LockManager; +import org.hl7.fhir.instance.model.api.IBaseResource; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.Map; +import java.util.Optional; + +/** + * Abstract Implementation of {@link DhisToFhirTransformer} for transforming DHIS 2 + * read-only metadata to a specific FHIR resource. + * + * @param the concrete type of the DHIS 2 resource that is processed by this transformer. + * @param the concrete type of the FHIR resource to which the DHIS 2 resource should be transformed. + * @param the concrete type of the transformer rule that is processed by this transformer. + * @author volsch + */ +public abstract class AbstractReadOnlyDhisMetadataToTypedFhirTransformer extends AbstractReadOnlyDhisMetadataToFhirTransformer +{ + protected AbstractReadOnlyDhisMetadataToTypedFhirTransformer( @Nonnull ScriptExecutor scriptExecutor, @Nonnull LockManager lockManager, @Nonnull SystemRepository systemRepository, @Nonnull FhirResourceRepository fhirResourceRepository, + @Nonnull FhirDhisAssignmentRepository fhirDhisAssignmentRepository ) + { + super( scriptExecutor, lockManager, systemRepository, fhirResourceRepository, fhirDhisAssignmentRepository ); + } + + @Nonnull + protected abstract FhirResourceType getFhirResourceType(); + + @Nullable + @Override + public final DhisToFhirTransformOutcome transform( @Nonnull FhirClient fhirClient, @Nonnull DhisToFhirTransformerContext context, @Nonnull R input, @Nonnull RuleInfo ruleInfo, @Nonnull Map scriptVariables ) throws TransformerException + { + if ( getFhirResourceType().equals( ruleInfo.getRule().getFhirResourceType() ) ) + { + return null; + } + + return transformInternal( fhirClient, context, input, ruleInfo, scriptVariables ); + } + + @Nonnull + @Override + protected Optional getActiveResource( @Nonnull FhirClient fhirClient, @Nonnull DhisToFhirTransformerContext context, @Nonnull RuleInfo ruleInfo, @Nonnull Map scriptVariables ) throws TransformerException + { + return Optional.empty(); + } + + @Nullable + protected DhisToFhirTransformOutcome transformInternal( @Nonnull FhirClient fhirClient, @Nonnull DhisToFhirTransformerContext context, @Nonnull R input, + @Nonnull RuleInfo ruleInfo, @Nonnull Map scriptVariables ) throws TransformerException + { + // method can be overridden + return null; + } +} diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/OrganizationUnitToFhirSearchState.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/DhisMetadataToFhirSearchState.java similarity index 89% rename from fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/OrganizationUnitToFhirSearchState.java rename to fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/DhisMetadataToFhirSearchState.java index 51a8bbce..18aef7bb 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/OrganizationUnitToFhirSearchState.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/DhisMetadataToFhirSearchState.java @@ -31,17 +31,17 @@ import org.dhis2.fhir.adapter.fhir.transform.dhis.DhisToFhirSearchState; /** - * Implementation of {@link DhisToFhirSearchState} for organization units. + * Implementation of {@link DhisToFhirSearchState} for DHIS2 metadata. * * @author volsch */ -public class OrganizationUnitToFhirSearchState implements DhisToFhirSearchState +public class DhisMetadataToFhirSearchState implements DhisToFhirSearchState { private final int from; private final boolean more; - public OrganizationUnitToFhirSearchState( int from, boolean more ) + public DhisMetadataToFhirSearchState( int from, boolean more ) { this.from = from; this.more = more; diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/PreparedOrganizationUnitDhisToFhirSearch.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/PreparedDhisMetadataToFhirSearch.java similarity index 80% rename from fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/PreparedOrganizationUnitDhisToFhirSearch.java rename to fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/PreparedDhisMetadataToFhirSearch.java index 768ef96f..31675dcd 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/PreparedOrganizationUnitDhisToFhirSearch.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/PreparedDhisMetadataToFhirSearch.java @@ -29,7 +29,7 @@ */ import ca.uhn.fhir.rest.param.DateRangeParam; -import org.dhis2.fhir.adapter.fhir.metadata.model.OrganizationUnitRule; +import org.dhis2.fhir.adapter.fhir.metadata.model.AbstractRule; import org.dhis2.fhir.adapter.fhir.metadata.model.RuleInfo; import org.dhis2.fhir.adapter.fhir.model.FhirVersion; import org.dhis2.fhir.adapter.fhir.transform.dhis.PreparedDhisToFhirSearch; @@ -41,13 +41,14 @@ import java.util.Map; /** - * Implementation of {@link PreparedDhisToFhirSearch} for organization units. + * Implementation of {@link PreparedDhisToFhirSearch} for DHIS 2 metadata. * + * @param the concrete type of the rule that processes the metadata. * @author volsch */ -public class PreparedOrganizationUnitDhisToFhirSearch extends AbstractPreparedDhisToFhirSearch +public class PreparedDhisMetadataToFhirSearch extends AbstractPreparedDhisToFhirSearch { - public PreparedOrganizationUnitDhisToFhirSearch( @Nonnull FhirVersion fhirVersion, @Nonnull List> ruleInfos, @Nullable Map> filter, @Nullable DateRangeParam lastUpdatedDateRange, int count ) + public PreparedDhisMetadataToFhirSearch( @Nonnull FhirVersion fhirVersion, @Nonnull List> ruleInfos, @Nullable Map> filter, @Nullable DateRangeParam lastUpdatedDateRange, int count ) { super( fhirVersion, ruleInfos, filter, lastUpdatedDateRange, count ); } diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/OrganizationUnitResolver.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/orgunit/OrganizationUnitResolver.java similarity index 99% rename from fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/OrganizationUnitResolver.java rename to fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/orgunit/OrganizationUnitResolver.java index c9e0c508..e518b293 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/OrganizationUnitResolver.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/orgunit/OrganizationUnitResolver.java @@ -1,4 +1,4 @@ -package org.dhis2.fhir.adapter.fhir.transform.dhis.impl.metadata; +package org.dhis2.fhir.adapter.fhir.transform.dhis.impl.metadata.orgunit; /* * Copyright (c) 2004-2019, University of Oslo diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/orgunit/OrganizationUnitToFhirDataProvider.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/orgunit/OrganizationUnitToFhirDataProvider.java new file mode 100644 index 00000000..eed7cf79 --- /dev/null +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/orgunit/OrganizationUnitToFhirDataProvider.java @@ -0,0 +1,77 @@ +package org.dhis2.fhir.adapter.fhir.transform.dhis.impl.metadata.orgunit; + +/* + * 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.DhisResourceType; +import org.dhis2.fhir.adapter.dhis.orgunit.OrganizationUnit; +import org.dhis2.fhir.adapter.dhis.orgunit.OrganizationUnitService; +import org.dhis2.fhir.adapter.fhir.metadata.model.OrganizationUnitRule; +import org.dhis2.fhir.adapter.fhir.model.FhirVersion; +import org.dhis2.fhir.adapter.fhir.script.ScriptExecutor; +import org.dhis2.fhir.adapter.fhir.transform.dhis.DhisToFhirDataProvider; +import org.dhis2.fhir.adapter.fhir.transform.dhis.impl.metadata.AbstractDhisMetadataToFhirDataProvider; +import org.springframework.stereotype.Component; + +import javax.annotation.Nonnull; +import java.util.Set; + +/** + * Implementation of {@link DhisToFhirDataProvider} for DHIS2 Organisation Units. + * + * @author volsch + */ +@Component +public class OrganizationUnitToFhirDataProvider extends AbstractDhisMetadataToFhirDataProvider +{ + public OrganizationUnitToFhirDataProvider( @Nonnull ScriptExecutor scriptExecutor, @Nonnull OrganizationUnitService organizationUnitService ) + { + super( scriptExecutor, organizationUnitService ); + } + + @Nonnull + @Override + public Set getFhirVersions() + { + return FhirVersion.ALL; + } + + @Nonnull + @Override + public DhisResourceType getDhisResourceType() + { + return DhisResourceType.ORGANIZATION_UNIT; + } + + @Nonnull + @Override + protected Class getRuleClass() + { + return OrganizationUnitRule.class; + } +} diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/OrganizationUnitToFhirRequestResolver.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/orgunit/OrganizationUnitToFhirRequestResolver.java similarity index 72% rename from fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/OrganizationUnitToFhirRequestResolver.java rename to fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/orgunit/OrganizationUnitToFhirRequestResolver.java index a81e9b1d..31891a8c 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/OrganizationUnitToFhirRequestResolver.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/orgunit/OrganizationUnitToFhirRequestResolver.java @@ -1,4 +1,4 @@ -package org.dhis2.fhir.adapter.fhir.transform.dhis.impl.metadata; +package org.dhis2.fhir.adapter.fhir.transform.dhis.impl.metadata.orgunit; /* * Copyright (c) 2004-2019, University of Oslo @@ -31,12 +31,10 @@ import org.dhis2.fhir.adapter.dhis.model.DhisResource; import org.dhis2.fhir.adapter.dhis.model.DhisResourceType; import org.dhis2.fhir.adapter.dhis.orgunit.OrganizationUnit; -import org.dhis2.fhir.adapter.fhir.metadata.model.AbstractRule; -import org.dhis2.fhir.adapter.fhir.metadata.model.RuleInfo; import org.dhis2.fhir.adapter.fhir.metadata.repository.FhirClientRepository; -import org.dhis2.fhir.adapter.fhir.metadata.repository.OrganizationUnitRuleRepository; -import org.dhis2.fhir.adapter.fhir.transform.dhis.impl.AbstractDhisToFhirRequestResolver; +import org.dhis2.fhir.adapter.fhir.metadata.repository.RuleRepository; import org.dhis2.fhir.adapter.fhir.transform.dhis.impl.DhisToFhirRequestResolver; +import org.dhis2.fhir.adapter.fhir.transform.dhis.impl.metadata.AbstractDhisMetadataToFhirRequestResolver; import org.dhis2.fhir.adapter.fhir.transform.dhis.model.DhisRequest; import org.dhis2.fhir.adapter.fhir.transform.scripted.ImmutableScriptedOrganizationUnit; import org.dhis2.fhir.adapter.fhir.transform.scripted.ScriptedDhisResource; @@ -44,8 +42,6 @@ import org.springframework.stereotype.Component; import javax.annotation.Nonnull; -import java.util.List; -import java.util.stream.Collectors; /** * Implementation of {@link DhisToFhirRequestResolver} for organization units. @@ -53,14 +49,11 @@ * @author volsch */ @Component -public class OrganizationUnitToFhirRequestResolver extends AbstractDhisToFhirRequestResolver +public class OrganizationUnitToFhirRequestResolver extends AbstractDhisMetadataToFhirRequestResolver { - private final OrganizationUnitRuleRepository ruleRepository; - - public OrganizationUnitToFhirRequestResolver( @Nonnull FhirClientRepository fhirClientRepository, OrganizationUnitRuleRepository ruleRepository ) + public OrganizationUnitToFhirRequestResolver( @Nonnull FhirClientRepository fhirClientRepository, @Nonnull RuleRepository ruleRepository ) { - super( fhirClientRepository ); - this.ruleRepository = ruleRepository; + super( fhirClientRepository, ruleRepository ); } @Nonnull @@ -70,20 +63,6 @@ public DhisResourceType getDhisResourceType() return DhisResourceType.ORGANIZATION_UNIT; } - @Nonnull - @Override - public List> resolveRules( @Nonnull ScriptedDhisResource dhisResource ) - { - return ruleRepository.findAllExp().stream().sorted().collect( Collectors.toList() ); - } - - @Nonnull - @Override - public List> resolveRules( @Nonnull ScriptedDhisResource dhisResource, @Nonnull List> rules ) - { - return rules.stream().sorted().collect( Collectors.toList() ); - } - @Nonnull @Override public ScriptedDhisResource convert( @Nonnull DhisResource dhisResource, @Nonnull DhisRequest dhisRequest ) diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/orgunit/OrganizationUnitToFhirTransformer.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/orgunit/OrganizationUnitToFhirTransformer.java new file mode 100644 index 00000000..89b8a2a2 --- /dev/null +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/orgunit/OrganizationUnitToFhirTransformer.java @@ -0,0 +1,132 @@ +package org.dhis2.fhir.adapter.fhir.transform.dhis.impl.metadata.orgunit; + +/* + * 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.DhisResourceType; +import org.dhis2.fhir.adapter.dhis.orgunit.OrganizationUnitService; +import org.dhis2.fhir.adapter.fhir.data.repository.FhirDhisAssignmentRepository; +import org.dhis2.fhir.adapter.fhir.metadata.model.ExecutableScript; +import org.dhis2.fhir.adapter.fhir.metadata.model.FhirClient; +import org.dhis2.fhir.adapter.fhir.metadata.model.OrganizationUnitRule; +import org.dhis2.fhir.adapter.fhir.metadata.model.RuleInfo; +import org.dhis2.fhir.adapter.fhir.metadata.model.ScriptVariable; +import org.dhis2.fhir.adapter.fhir.metadata.repository.SystemRepository; +import org.dhis2.fhir.adapter.fhir.model.FhirVersion; +import org.dhis2.fhir.adapter.fhir.repository.FhirResourceRepository; +import org.dhis2.fhir.adapter.fhir.script.ScriptExecutor; +import org.dhis2.fhir.adapter.fhir.transform.dhis.DhisToFhirTransformerContext; +import org.dhis2.fhir.adapter.fhir.transform.dhis.impl.DhisToFhirTransformer; +import org.dhis2.fhir.adapter.fhir.transform.dhis.impl.metadata.AbstractReadOnlyDhisMetadataToFhirTransformer; +import org.dhis2.fhir.adapter.fhir.transform.scripted.ScriptedOrganizationUnit; +import org.dhis2.fhir.adapter.lock.LockManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.Map; +import java.util.Set; + +/** + * Implementation of {@link DhisToFhirTransformer} for transforming DHIS 2 + * organization unit to FHIR resources. + * + * @author volsch + */ +@Component +public class OrganizationUnitToFhirTransformer extends AbstractReadOnlyDhisMetadataToFhirTransformer +{ + private final Logger logger = LoggerFactory.getLogger( getClass() ); + + private final OrganizationUnitService organizationUnitService; + + public OrganizationUnitToFhirTransformer( @Nonnull ScriptExecutor scriptExecutor, @Nonnull LockManager lockManager, @Nonnull SystemRepository systemRepository, @Nonnull FhirResourceRepository fhirResourceRepository, + @Nonnull FhirDhisAssignmentRepository fhirDhisAssignmentRepository, @Nonnull OrganizationUnitService organizationUnitService ) + { + super( scriptExecutor, lockManager, systemRepository, fhirResourceRepository, fhirDhisAssignmentRepository ); + this.organizationUnitService = organizationUnitService; + } + + @Nonnull + @Override + public Set getFhirVersions() + { + return FhirVersion.ALL; + } + + @Nonnull + @Override + public DhisResourceType getDhisResourceType() + { + return DhisResourceType.ORGANIZATION_UNIT; + } + + @Nonnull + @Override + public Class getDhisResourceClass() + { + return ScriptedOrganizationUnit.class; + } + + @Nonnull + @Override + public Class getRuleClass() + { + return OrganizationUnitRule.class; + } + + @Override + protected void addAdditionalVariables( @Nonnull FhirClient fhirClient, @Nonnull DhisToFhirTransformerContext context, @Nonnull RuleInfo ruleInfo, @Nonnull Map variables ) + { + variables.put( ScriptVariable.ORGANIZATION_UNIT_RESOLVER.getVariableName(), new OrganizationUnitResolver( + organizationUnitService, getFhirResourceRepository(), fhirClient, context, ruleInfo, variables, + new DefaultIdentifierValueProvider() ) ); + } + + @Override + @Nullable + protected String getIdentifierValue( @Nonnull DhisToFhirTransformerContext context, @Nonnull RuleInfo ruleInfo, @Nullable ExecutableScript identifierLookupScript, @Nonnull ScriptedOrganizationUnit scriptedOrganizationUnit, + @Nonnull Map scriptVariables ) + { + String identifier = super.getIdentifierValue( context, ruleInfo, identifierLookupScript, scriptedOrganizationUnit, scriptVariables ); + + if ( identifier != null ) + { + return identifier; + } + + if ( identifierLookupScript == null ) + { + identifier = executeScript( context, ruleInfo, ruleInfo.getRule().getIdentifierLookupScript(), scriptVariables, String.class ); + } + + return identifier; + } +} diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/program/ProgramMetadataToFhirDataProvider.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/program/ProgramMetadataToFhirDataProvider.java new file mode 100644 index 00000000..0cb8c4e1 --- /dev/null +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/program/ProgramMetadataToFhirDataProvider.java @@ -0,0 +1,77 @@ +package org.dhis2.fhir.adapter.fhir.transform.dhis.impl.metadata.program; + +/* + * 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.DhisResourceType; +import org.dhis2.fhir.adapter.dhis.tracker.program.Program; +import org.dhis2.fhir.adapter.dhis.tracker.program.ProgramMetadataService; +import org.dhis2.fhir.adapter.fhir.metadata.model.ProgramMetadataRule; +import org.dhis2.fhir.adapter.fhir.model.FhirVersion; +import org.dhis2.fhir.adapter.fhir.script.ScriptExecutor; +import org.dhis2.fhir.adapter.fhir.transform.dhis.DhisToFhirDataProvider; +import org.dhis2.fhir.adapter.fhir.transform.dhis.impl.metadata.AbstractDhisMetadataToFhirDataProvider; +import org.springframework.stereotype.Component; + +import javax.annotation.Nonnull; +import java.util.Set; + +/** + * Implementation of {@link DhisToFhirDataProvider} for DHIS2 Program Metadata. + * + * @author volsch + */ +@Component +public class ProgramMetadataToFhirDataProvider extends AbstractDhisMetadataToFhirDataProvider +{ + public ProgramMetadataToFhirDataProvider( @Nonnull ScriptExecutor scriptExecutor, @Nonnull ProgramMetadataService programMetadataService ) + { + super( scriptExecutor, programMetadataService ); + } + + @Nonnull + @Override + public Set getFhirVersions() + { + return FhirVersion.ALL; + } + + @Nonnull + @Override + public DhisResourceType getDhisResourceType() + { + return DhisResourceType.PROGRAM_METADATA; + } + + @Nonnull + @Override + protected Class getRuleClass() + { + return ProgramMetadataRule.class; + } +} diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/program/ProgramMetadataToFhirRequestResolver.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/program/ProgramMetadataToFhirRequestResolver.java new file mode 100644 index 00000000..f5a16ce4 --- /dev/null +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/metadata/program/ProgramMetadataToFhirRequestResolver.java @@ -0,0 +1,72 @@ +package org.dhis2.fhir.adapter.fhir.transform.dhis.impl.metadata.program; + +/* + * 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.DhisMetadata; +import org.dhis2.fhir.adapter.dhis.model.DhisResource; +import org.dhis2.fhir.adapter.dhis.model.DhisResourceType; +import org.dhis2.fhir.adapter.fhir.metadata.repository.FhirClientRepository; +import org.dhis2.fhir.adapter.fhir.metadata.repository.RuleRepository; +import org.dhis2.fhir.adapter.fhir.transform.dhis.impl.DhisToFhirRequestResolver; +import org.dhis2.fhir.adapter.fhir.transform.dhis.impl.metadata.AbstractDhisMetadataToFhirRequestResolver; +import org.dhis2.fhir.adapter.fhir.transform.dhis.model.DhisRequest; +import org.dhis2.fhir.adapter.fhir.transform.scripted.ImmutableScriptedDhisMetadata; +import org.dhis2.fhir.adapter.fhir.transform.scripted.ScriptedDhisResource; +import org.dhis2.fhir.adapter.fhir.transform.scripted.WritableScriptedDhisMetadata; +import org.springframework.stereotype.Component; + +import javax.annotation.Nonnull; + +/** + * Implementation of {@link DhisToFhirRequestResolver} for DHIS2 program metadata. + * + * @author volsch + */ +@Component +public class ProgramMetadataToFhirRequestResolver extends AbstractDhisMetadataToFhirRequestResolver +{ + public ProgramMetadataToFhirRequestResolver( @Nonnull FhirClientRepository fhirClientRepository, @Nonnull RuleRepository ruleRepository ) + { + super( fhirClientRepository, ruleRepository ); + } + + @Nonnull + @Override + public DhisResourceType getDhisResourceType() + { + return DhisResourceType.PROGRAM_METADATA; + } + + @Nonnull + @Override + public ScriptedDhisResource convert( @Nonnull DhisResource dhisResource, @Nonnull DhisRequest dhisRequest ) + { + return new ImmutableScriptedDhisMetadata( new WritableScriptedDhisMetadata<>( (DhisResource & DhisMetadata) dhisResource ) ); + } +} diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/program/PreparedProgramStageToFhirSearch.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/program/PreparedProgramStageToFhirSearch.java index 35076aea..b0189d80 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/program/PreparedProgramStageToFhirSearch.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/program/PreparedProgramStageToFhirSearch.java @@ -64,11 +64,14 @@ public ProgramStageId getNextProgramStageId( @Nullable ProgramStageId previousPr { return programStageIds.get( 0 ); } + final int index = programStageIds.indexOf( previousProgramStageId ); - if ( (index + 1) >= programStageIds.size() ) + + if ( index + 1 >= programStageIds.size() ) { return null; } + return programStageIds.get( index + 1 ); } } diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/program/ProgramStageToFhirDataProvider.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/program/ProgramStageToFhirDataProvider.java index e3483644..6143ba7e 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/program/ProgramStageToFhirDataProvider.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/program/ProgramStageToFhirDataProvider.java @@ -84,6 +84,13 @@ public ProgramStageToFhirDataProvider( @Nonnull ScriptExecutor scriptExecutor, @ this.eventService = eventService; } + @Nonnull + @Override + public Set getFhirVersions() + { + return FhirVersion.ALL; + } + @Nonnull @Override public DhisResourceType getDhisResourceType() @@ -115,7 +122,7 @@ public PreparedDhisToFhirSearch prepareSearch( @Nonnull FhirVersion fhirVersion, .map( ri -> new ReferenceTuple( ri.getRule().getProgramStage().getProgram().getProgramReference(), ri.getRule().getProgramStage().getProgramStageReference() ) ) .collect( Collectors.toCollection( TreeSet::new ) ); final Set programStageIds = refs.stream().map( ref -> { - final Program program = metadataService.findProgramByReference( ref.getProgramReference() ) + final Program program = metadataService.findMetadataByReference( ref.getProgramReference() ) .orElseThrow( () -> new TransformerMappingException( "Program does not exist: " + ref.getProgramReference() ) ); final ProgramStage programStage = program.getOptionalStage( ref.getProgramStageReference() ) .orElseThrow( () -> new TransformerMappingException( "Program stage does not exist: " + ref.getProgramStageReference() ) ); diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/program/ProgramStageToFhirRequestResolver.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/program/ProgramStageToFhirRequestResolver.java index 3e04f218..532e6a2c 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/program/ProgramStageToFhirRequestResolver.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/program/ProgramStageToFhirRequestResolver.java @@ -145,7 +145,7 @@ public ScriptedDhisResource convert( @Nonnull DhisResource dhisResource, @Nonnul final ScriptedTrackedEntityInstance scriptedTrackedEntityInstance = new ImmutableScriptedTrackedEntityInstance( new WritableScriptedTrackedEntityInstance( trackedEntityAttributes, trackedEntityType, tei, valueConverter ) ); - final Program program = programMetadataService.findProgramByReference( new Reference( event.getProgramId(), ReferenceType.ID ) ) + final Program program = programMetadataService.findMetadataByReference( new Reference( event.getProgramId(), ReferenceType.ID ) ) .orElseThrow( () -> new TransformerDataException( "Program " + event.getProgramId() + " of event " + event.getId() + " could not be found." ) ); final ProgramStage programStage = program.getOptionalStage( new Reference( event.getProgramStageId(), ReferenceType.ID ) ) .orElseThrow( () -> new TransformerDataException( "Program stage " + event.getProgramStageId() + " of event " + event.getId() + diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/trackedentity/TrackedEntityToFhirDataProvider.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/trackedentity/TrackedEntityToFhirDataProvider.java index 3ae613b4..06e784a4 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/trackedentity/TrackedEntityToFhirDataProvider.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/trackedentity/TrackedEntityToFhirDataProvider.java @@ -89,6 +89,13 @@ public DhisResourceType getDhisResourceType() return DhisResourceType.TRACKED_ENTITY; } + @Nonnull + @Override + public Set getFhirVersions() + { + return FhirVersion.ALL; + } + @Nonnull @Override protected Class getRuleClass() diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/fhir/impl/program/FhirToEnrollmentTransformer.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/fhir/impl/program/FhirToEnrollmentTransformer.java index a4b5ccc9..f69ac3c4 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/fhir/impl/program/FhirToEnrollmentTransformer.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/fhir/impl/program/FhirToEnrollmentTransformer.java @@ -366,7 +366,7 @@ protected Program getProgram( @Nonnull FhirToDhisTransformerContext context, @No throw new TransformerDataException( "FHIR resource does not contain a a reference to a tracker program." ); } - final Program program = programMetadataService.findProgramByReference( programRef ).orElse( null ); + final Program program = programMetadataService.findMetadataByReference( programRef ).orElse( null ); if ( program == null ) { diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/fhir/impl/program/FhirToProgramStageTransformer.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/fhir/impl/program/FhirToProgramStageTransformer.java index 3f60d91c..647a66e6 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/fhir/impl/program/FhirToProgramStageTransformer.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/fhir/impl/program/FhirToProgramStageTransformer.java @@ -289,7 +289,7 @@ else if ( !ruleInfo.getDhisDataReferences().isEmpty() ) final Event event = getResourceById( dhisFhirResourceId.getId() ).orElse( null ); if ( event != null ) { - final Program program = programMetadataService.findProgramByReference( new Reference( event.getProgramId(), ReferenceType.ID ) ) + final Program program = programMetadataService.findMetadataByReference( new Reference( event.getProgramId(), ReferenceType.ID ) ) .orElseThrow( () -> new TransformerDataException( "Program " + event.getProgramId() + " of event " + event.getId() + " could not be found." ) ); final ProgramStage programStage = program.getOptionalStage( ruleInfo.getRule().getProgramStage().getProgramStageReference() ).orElseThrow( () -> new TransformerMappingException( "Rule " + ruleInfo + " requires program stage \"" + ruleInfo.getRule().getProgramStage().getProgramStageReference() + "\" that is not included in program \"" + ruleInfo.getRule().getProgramStage().getProgram().getName() + "\"." ) ); @@ -322,7 +322,7 @@ else if ( !ruleInfo.getDhisDataReferences().isEmpty() ) protected boolean addBasicScriptVariables( @Nonnull Map variables, @Nonnull FhirToDhisTransformerContext context, @Nonnull RuleInfo ruleInfo, @Nonnull FhirResourceMapping resourceMapping ) throws TransformerException { - final Program program = programMetadataService.findProgramByReference( ruleInfo.getRule().getProgramStage().getProgram().getProgramReference() ) + final Program program = programMetadataService.findMetadataByReference( ruleInfo.getRule().getProgramStage().getProgram().getProgramReference() ) .orElseThrow( () -> new TransformerMappingException( "Mapping " + ruleInfo + " requires program \"" + ruleInfo.getRule().getProgramStage().getProgram().getProgramReference() + "\" that does not exist." ) ); variables.put( ScriptVariable.PROGRAM.getVariableName(), program ); diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/scripted/ImmutableScriptedDhisMetadata.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/scripted/ImmutableScriptedDhisMetadata.java new file mode 100644 index 00000000..b2198951 --- /dev/null +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/scripted/ImmutableScriptedDhisMetadata.java @@ -0,0 +1,135 @@ +package org.dhis2.fhir.adapter.fhir.transform.scripted; + +/* + * 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.DhisResourceId; +import org.dhis2.fhir.adapter.dhis.model.DhisResourceType; +import org.dhis2.fhir.adapter.fhir.transform.TransformerException; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.io.Serializable; +import java.time.ZonedDateTime; + +/** + * Base implementation of scripted metadata. + * + * @author volsch + */ +public class ImmutableScriptedDhisMetadata implements ScriptedDhisMetadata, Serializable +{ + private static final long serialVersionUID = -3081103677950925231L; + + private final ScriptedDhisMetadata metadata; + + public ImmutableScriptedDhisMetadata( @Nonnull ScriptedDhisMetadata metadata ) + { + this.metadata = metadata; + } + + @Override + @Nullable + public String getCode() + { + return metadata.getCode(); + } + + @Override + @Nullable + public String getName() + { + return metadata.getName(); + } + + @Override + @Nullable + public String getId() + { + return metadata.getId(); + } + + @Override + @Nonnull + public DhisResourceType getResourceType() + { + return metadata.getResourceType(); + } + + @Override + @Nullable + public DhisResourceId getResourceId() + { + return metadata.getResourceId(); + } + + @Override + public boolean isNewResource() + { + return metadata.isNewResource(); + } + + @Override + public boolean isLocal() + { + return metadata.isLocal(); + } + + @Override + public boolean isDeleted() + { + return metadata.isDeleted(); + } + + @Override + @Nullable + public ZonedDateTime getLastUpdated() + { + return metadata.getLastUpdated(); + } + + @Override + @Nullable + public String getOrganizationUnitId() + { + return metadata.getOrganizationUnitId(); + } + + @Override + @Nullable + public ScriptedTrackedEntityInstance getTrackedEntityInstance() + { + return metadata.getTrackedEntityInstance(); + } + + @Override + public void validate() throws TransformerException + { + metadata.validate(); + } +} diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/CustomOrganizationUnitRuleRepository.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/scripted/ScriptedDhisMetadata.java similarity index 72% rename from fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/CustomOrganizationUnitRuleRepository.java rename to fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/scripted/ScriptedDhisMetadata.java index 61205245..d1d515cb 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/CustomOrganizationUnitRuleRepository.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/scripted/ScriptedDhisMetadata.java @@ -1,7 +1,7 @@ -package org.dhis2.fhir.adapter.fhir.metadata.repository; +package org.dhis2.fhir.adapter.fhir.transform.scripted; /* - * Copyright (c) 2004-2018, University of Oslo + * Copyright (c) 2004-2019, University of Oslo * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,19 +28,21 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import org.dhis2.fhir.adapter.fhir.metadata.model.OrganizationUnitRule; -import org.dhis2.fhir.adapter.fhir.metadata.model.RuleInfo; -import org.springframework.data.rest.core.annotation.RestResource; +import org.dhis2.fhir.adapter.scriptable.Scriptable; -import javax.annotation.Nonnull; -import java.util.Collection; +import javax.annotation.Nullable; /** - * Custom rule repository for organization unit rules. + * Mutable or immutable metadata resource that can be used by scripts safely. + * + * @author volsch */ -public interface CustomOrganizationUnitRuleRepository +@Scriptable +public interface ScriptedDhisMetadata extends ScriptedDhisResource { - @RestResource( exported = false ) - @Nonnull - Collection> findAllExp(); + @Nullable + String getCode(); + + @Nullable + String getName(); } diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/scripted/ScriptedOrganizationUnit.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/scripted/ScriptedOrganizationUnit.java index 561ccd21..baf9f130 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/scripted/ScriptedOrganizationUnit.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/scripted/ScriptedOrganizationUnit.java @@ -1,7 +1,7 @@ package org.dhis2.fhir.adapter.fhir.transform.scripted; /* - * Copyright (c) 2004-2018, University of Oslo + * Copyright (c) 2004-2019, University of Oslo * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -39,7 +39,7 @@ * @author volsch */ @Scriptable -public interface ScriptedOrganizationUnit extends ScriptedDhisResource +public interface ScriptedOrganizationUnit extends ScriptedDhisMetadata { @Nullable String getCode(); diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/scripted/WritableScriptedDhisMetadata.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/scripted/WritableScriptedDhisMetadata.java new file mode 100644 index 00000000..c07a6eb9 --- /dev/null +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/scripted/WritableScriptedDhisMetadata.java @@ -0,0 +1,140 @@ +package org.dhis2.fhir.adapter.fhir.transform.scripted; + +/* + * 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.DhisMetadata; +import org.dhis2.fhir.adapter.dhis.model.DhisResource; +import org.dhis2.fhir.adapter.dhis.model.DhisResourceId; +import org.dhis2.fhir.adapter.dhis.model.DhisResourceType; +import org.dhis2.fhir.adapter.fhir.transform.TransformerException; +import org.dhis2.fhir.adapter.scriptable.Scriptable; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.io.Serializable; +import java.time.ZonedDateTime; + +/** + * Implementation of writable scripted metadata. + * + * @param concrete metadata class. + * @author volsch + */ +@Scriptable +public class WritableScriptedDhisMetadata implements ScriptedDhisMetadata, Serializable +{ + private static final long serialVersionUID = 8245822986881397171L; + + protected final M metadata; + + public WritableScriptedDhisMetadata( @Nonnull M metadata ) + { + this.metadata = metadata; + } + + @Nullable + @Override + public String getCode() + { + return metadata.getCode(); + } + + @Nullable + @Override + public String getName() + { + return metadata.getName(); + } + + @Nullable + @Override + public String getId() + { + return metadata.getId(); + } + + @Nonnull + @Override + public DhisResourceType getResourceType() + { + return metadata.getResourceType(); + } + + @Nullable + @Override + public DhisResourceId getResourceId() + { + return metadata.getResourceId(); + } + + @Override + public boolean isNewResource() + { + return metadata.isNewResource(); + } + + @Override + public boolean isLocal() + { + return metadata.isLocal(); + } + + @Override + public boolean isDeleted() + { + return metadata.isDeleted(); + } + + @Nullable + @Override + public ZonedDateTime getLastUpdated() + { + return metadata.getLastUpdated(); + } + + @Nullable + @Override + public String getOrganizationUnitId() + { + return metadata.getOrgUnitId(); + } + + @Nullable + @Override + public ScriptedTrackedEntityInstance getTrackedEntityInstance() + { + return null; + } + + @Override + public void validate() throws TransformerException + { + // nothing to be done + } +} diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/scripted/WritableScriptedOrganizationUnit.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/scripted/WritableScriptedOrganizationUnit.java index 55a4eb8c..f5a1b5eb 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/scripted/WritableScriptedOrganizationUnit.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/scripted/WritableScriptedOrganizationUnit.java @@ -28,15 +28,10 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import org.dhis2.fhir.adapter.dhis.model.DhisResourceId; -import org.dhis2.fhir.adapter.dhis.model.DhisResourceType; import org.dhis2.fhir.adapter.dhis.orgunit.OrganizationUnit; -import org.dhis2.fhir.adapter.fhir.transform.TransformerException; -import org.dhis2.fhir.adapter.scriptable.ScriptMethod; import org.dhis2.fhir.adapter.scriptable.ScriptType; import org.dhis2.fhir.adapter.scriptable.Scriptable; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.io.Serializable; import java.time.ZonedDateTime; @@ -49,149 +44,66 @@ */ @Scriptable @ScriptType( value = "OrganizationUnit", transformDataType = "DHIS_ORGANIZATION_UNIT", description = "Organization unit." ) -public class WritableScriptedOrganizationUnit implements ScriptedOrganizationUnit, Serializable +public class WritableScriptedOrganizationUnit extends WritableScriptedDhisMetadata implements ScriptedOrganizationUnit, Serializable { private static final long serialVersionUID = -9043373621936561310L; - private final OrganizationUnit organizationUnit; - public WritableScriptedOrganizationUnit( OrganizationUnit organizationUnit ) { - this.organizationUnit = organizationUnit; - } - - @Override - public boolean isNewResource() - { - return false; - } - - @Override - public boolean isLocal() - { - return organizationUnit.isLocal(); - } - - @Override - public boolean isDeleted() - { - return false; - } - - @Nullable - @Override - public String getId() - { - return organizationUnit.getId(); - } - - @Nonnull - @Override - public DhisResourceType getResourceType() - { - return organizationUnit.getResourceType(); - } - - @Nullable - @Override - public DhisResourceId getResourceId() - { - return organizationUnit.getResourceId(); - } - - @Nullable - @Override - @ScriptMethod( description = "Returns the date and time when the resource has been updated the last time or null if this is a new resource." ) - public ZonedDateTime getLastUpdated() - { - return organizationUnit.getLastUpdated(); - } - - @Nullable - @Override - public String getOrganizationUnitId() - { - return organizationUnit.getId(); - } - - @Nullable - @Override - public ScriptedTrackedEntityInstance getTrackedEntityInstance() - { - return null; - } - - @Nullable - @Override - public String getCode() - { - return organizationUnit.getCode(); - } - - @Nullable - @Override - public String getName() - { - return organizationUnit.getName(); + super( organizationUnit ); } @Nullable @Override public String getShortName() { - return organizationUnit.getShortName(); + return metadata.getShortName(); } @Nullable @Override public String getDisplayName() { - return organizationUnit.getDisplayName(); + return metadata.getDisplayName(); } @Override public boolean isLeaf() { - return organizationUnit.isLeaf(); + return metadata.isLeaf(); } @Override public int getLevel() { - return organizationUnit.getLevel(); + return metadata.getLevel(); } @Nullable @Override public ZonedDateTime getOpeningDate() { - return organizationUnit.getOpeningDate(); + return metadata.getOpeningDate(); } @Nullable @Override public ZonedDateTime getClosedDate() { - return organizationUnit.getClosedDate(); + return metadata.getClosedDate(); } @Nullable @Override public String getParentId() { - return organizationUnit.getParentId(); + return metadata.getParentId(); } @Nullable @Override public String getCoordinates() { - return organizationUnit.getCoordinates(); - } - - @Override - public void validate() throws TransformerException - { - // nothing to be done since instance will not be modified currently + return metadata.getCoordinates(); } } diff --git a/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/transform/fhir/impl/program/FhirToEnrollmentTransformerTest.java b/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/transform/fhir/impl/program/FhirToEnrollmentTransformerTest.java index 4c89610e..2e65b89d 100644 --- a/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/transform/fhir/impl/program/FhirToEnrollmentTransformerTest.java +++ b/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/transform/fhir/impl/program/FhirToEnrollmentTransformerTest.java @@ -242,7 +242,7 @@ private void create( ZonedDateTime incidentDate ) Mockito.doReturn( Reference.createIdReference( "hsu82us82ia" ) ).when( scriptExecutor ) .execute( Mockito.same( programRefLookupScript ), Mockito.eq( FhirVersion.R4 ), Mockito.anyMap(), Mockito.anyMap(), Mockito.anyMap(), Mockito.eq( Reference.class ) ); - Mockito.doReturn( Optional.of( program ) ).when( programMetadataService ).findProgramByReference( Mockito.eq( Reference.createIdReference( "hsu82us82ia" ) ) ); + Mockito.doReturn( Optional.of( program ) ).when( programMetadataService ).findMetadataByReference( Mockito.eq( Reference.createIdReference( "hsu82us82ia" ) ) ); Mockito.doReturn( Optional.of( trackedEntityType ) ).when( trackedEntityMetadataService ).findTypeByReference( Mockito.eq( Reference.createIdReference( "js73jhsyus91" ) ) ); Mockito.doReturn( Collections.singletonList( trackedEntityRule ) ).when( trackedEntityRuleRepository ) .findByTypeRefs( (Collection) MockitoHamcrest.argThat( Matchers.containsInAnyOrder( Reference.createIdReference( "js73jhsyus91" ) ) ) ); diff --git a/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/transform/fhir/impl/program/FhirToProgramStageTransformerTest.java b/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/transform/fhir/impl/program/FhirToProgramStageTransformerTest.java index bde306a3..36b9beeb 100644 --- a/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/transform/fhir/impl/program/FhirToProgramStageTransformerTest.java +++ b/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/transform/fhir/impl/program/FhirToProgramStageTransformerTest.java @@ -162,7 +162,7 @@ public void setUp() trackedEntityType = new WritableTrackedEntityType(); trackedEntityType.setId( "jdsuewyui1oi" ); - Mockito.doReturn( Optional.of( program ) ).when( programMetadataService ).findProgramByReference( Mockito.eq( Reference.createIdReference( "jsheyu37anc" ) ) ); + Mockito.doReturn( Optional.of( program ) ).when( programMetadataService ).findMetadataByReference( Mockito.eq( Reference.createIdReference( "jsheyu37anc" ) ) ); Mockito.doReturn( Optional.of( trackedEntityType ) ).when( trackedEntityMetadataService ).findTypeByReference( Mockito.eq( Reference.createIdReference( "jdsuewyui1oi" ) ) ); fhirResourceMapping = new FhirResourceMapping(); diff --git a/metadata-sheet/src/main/java/org/dhis2/fhir/adapter/metadata/sheet/processor/MetadataSheetProgramImportProcessor.java b/metadata-sheet/src/main/java/org/dhis2/fhir/adapter/metadata/sheet/processor/MetadataSheetProgramImportProcessor.java index c8bda756..d6b7fb13 100644 --- a/metadata-sheet/src/main/java/org/dhis2/fhir/adapter/metadata/sheet/processor/MetadataSheetProgramImportProcessor.java +++ b/metadata-sheet/src/main/java/org/dhis2/fhir/adapter/metadata/sheet/processor/MetadataSheetProgramImportProcessor.java @@ -166,7 +166,7 @@ MetadataSheetMessageSeverity.ERROR, new MetadataSheetLocation( PROGRAM_SHEET_NAM return messageCollector; } - final Program program = programMetadataService.findProgramByReference( programRef ).orElse( null ); + final Program program = programMetadataService.findMetadataRefreshedByReference( programRef ).orElse( null ); TrackedEntityRule trackedEntityRule = null; if ( program == null ) diff --git a/metadata-sheet/src/main/java/org/dhis2/fhir/adapter/metadata/sheet/processor/MetadataSheetRuleImportProcessor.java b/metadata-sheet/src/main/java/org/dhis2/fhir/adapter/metadata/sheet/processor/MetadataSheetRuleImportProcessor.java index 501c7cb2..bbed7227 100644 --- a/metadata-sheet/src/main/java/org/dhis2/fhir/adapter/metadata/sheet/processor/MetadataSheetRuleImportProcessor.java +++ b/metadata-sheet/src/main/java/org/dhis2/fhir/adapter/metadata/sheet/processor/MetadataSheetRuleImportProcessor.java @@ -198,7 +198,7 @@ public MetadataSheetMessageCollector process( @Nonnull Workbook workbook ) return messageCollector; } - final Program program = programMetadataService.findProgramByReference( programRef ).orElse( null ); + final Program program = programMetadataService.findMetadataRefreshedByReference( programRef ).orElse( null ); if ( program == null ) {