Skip to content

Commit

Permalink
Updated entity relationships.
Browse files Browse the repository at this point in the history
  • Loading branch information
volsch committed Nov 19, 2018
1 parent 74b178d commit e4f01f9
Show file tree
Hide file tree
Showing 13 changed files with 142 additions and 25 deletions.
7 changes: 3 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,13 +128,12 @@ For the initial setup of the Adapter a simple user interface is provided. To acc

java -jar dhis2-fhir-adapter.war --adapter-setup=true

With the default configuration the initial setup user interface can be accessed in any web browser by using http://localhost:8081/setup. The web browser will ask for a username and password of a DHIS2 user that has privilege F_SYSTEM_SETTING. After
With the default configuration the initial setup user interface can be accessed in any web browser by using `http://localhost:8081/setup`. The web browser will ask for a username and password of a DHIS2 user that has privilege F_SYSTEM_SETTING. After
successful authentication a setup form will be displayed with further instructions and examples. The initial setup can be made once only and the initial setup form will not be accessible anymore.

### API for Administration and Mapping
The adapter provides REST interfaces for administration and mapping. The documentation is currently generated automatically when building the adapter. Unit test execution must not be skipped in this case when building the adapter. The documentation can be
found at docs/api-guide.html. If the Adapter has been started by command line without changing the port, then the guide is available at http://localhost:8081/docs/api-guide.html.
found at docs/api-guide.html. If the Adapter has been started by command line without changing the port, then the guide is available at `http://localhost:8081/docs/api-guide.html`.

The JavaScript API that is used to create rules and transformations is generated automatically when running the adapter. The script can be found at scripts/to-dhis2-all-mapping.js. If the Adapter has been started by command line without changing the port,
then the guide is available at http://localhost:8081/scripts/to-dhis2-all-mapping.js. The FHIR resources are exposed to JavaScript by [HAPI FHIR 3.6.0](http://hapifhir.io/) objects.

then the guide is available at `http://localhost:8081/scripts/to-dhis2-all-mapping.js`. The FHIR resources are exposed to JavaScript by [HAPI FHIR 3.6.0](http://hapifhir.io/) objects.
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ protected void configure( @Nonnull HttpSecurity http ) throws Exception
.antMatchers( HttpMethod.GET, "/actuator/info" ).permitAll()
.antMatchers( HttpMethod.GET, "/docs/**" ).permitAll()
.antMatchers( HttpMethod.GET, "/dhis/metadata/**" ).permitAll()
.antMatchers( HttpMethod.GET, "/script/**" ).permitAll()
.antMatchers( HttpMethod.GET, "/scripts/**" ).permitAll()
.antMatchers( HttpMethod.OPTIONS, "/api/**" ).permitAll()
.antMatchers( "/actuator/**" ).hasRole( AdapterAuthorities.ADMINISTRATION_AUTHORITY )
.anyRequest().authenticated()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,10 @@ public String doConvert( @Nonnull A source ) throws ConversionException
switch ( source.name() )
{
case "FEMALE":
return constantResolver.getByCode( GENDER_FEMALE_CONSTANT_CODE )
return constantResolver.findOneByCode( GENDER_FEMALE_CONSTANT_CODE )
.orElseThrow( () -> new ConversionException( "No constant with code " + GENDER_FEMALE_CONSTANT_CODE + " has been defined." ) ).getValue();
case "MALE":
return constantResolver.getByCode( GENDER_MALE_CONSTANT_CODE )
return constantResolver.findOneByCode( GENDER_MALE_CONSTANT_CODE )
.orElseThrow( () -> new ConversionException( "No constant with code " + GENDER_MALE_CONSTANT_CODE + " has been defined." ) ).getValue();
case "NULL":
case "OTHER":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

import org.springframework.data.rest.core.annotation.RestResource;

import javax.annotation.Nonnull;
import java.util.Optional;

Expand All @@ -44,6 +46,7 @@ public interface ConstantResolver
* @param code the code of the constant that should be resolved.
* @return the constant with the specified code.
*/
@RestResource( exported = false )
@Nonnull
Optional<Constant> getByCode( @Nonnull String code );
Optional<Constant> findOneByCode( @Nonnull String code );
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
*/

import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.dhis2.fhir.adapter.fhir.metadata.model.jackson.ScriptVariablePersistentSortedSetConverter;
import org.dhis2.fhir.adapter.jackson.ToManyPropertyFilter;
Expand All @@ -43,7 +42,6 @@
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
Expand Down Expand Up @@ -204,7 +202,7 @@ public void setArguments( List<ScriptArg> scriptVariables )
}

@SuppressWarnings( "JpaAttributeTypeInspection" )
@ElementCollection( fetch = FetchType.EAGER )
@ElementCollection
@CollectionTable( name = "fhir_script_variable", joinColumns = @JoinColumn( name = "script_id" ) )
@Column( name = "variable" )
@Enumerated( EnumType.STRING )
Expand All @@ -220,9 +218,8 @@ public void setVariables( SortedSet<ScriptVariable> variables )
this.variables = variables;
}

@OneToMany( mappedBy = "script", orphanRemoval = true, cascade = CascadeType.ALL, fetch = FetchType.EAGER )
@OneToMany( mappedBy = "script", orphanRemoval = true, cascade = CascadeType.ALL )
@OrderBy( "id" )
@JsonIgnore
public List<ScriptSource> getSources()
{
return sources;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Embeddable;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.OrderBy;
import javax.validation.Valid;
Expand Down Expand Up @@ -83,7 +82,7 @@ public void setBaseUrl( String baseUrl )
}

@SuppressWarnings( "JpaAttributeTypeInspection" )
@ElementCollection( fetch = FetchType.EAGER )
@ElementCollection
@CollectionTable( name = "fhir_remote_subscription_header", joinColumns = @JoinColumn( name = "remote_subscription_id" ) )
@OrderBy( "name,value" )
@JsonSerialize( converter = PersistentBagConverter.class )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.dhis2.fhir.adapter.fhir.metadata.model.ExecutableScriptInfo;
import org.dhis2.fhir.adapter.fhir.model.FhirVersion;
import org.springframework.data.rest.core.annotation.RestResource;
import org.springframework.security.access.prepost.PreAuthorize;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
Expand All @@ -46,5 +47,6 @@ public interface CustomExecutableScriptRepository
{
@RestResource( exported = false )
@Nonnull
@PreAuthorize( "permitAll()" )
Optional<ExecutableScriptInfo> findInfo( @Nullable ExecutableScript executableScript, @Nonnull FhirVersion fhirVersion );
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package org.dhis2.fhir.adapter.fhir.metadata.repository;

/*
* 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.RemoteSubscriptionResource;
import org.springframework.data.rest.core.annotation.RestResource;
import org.springframework.security.access.prepost.PreAuthorize;

import javax.annotation.Nonnull;
import java.util.Optional;
import java.util.UUID;

/**
* Custom repository for {@link RemoteSubscriptionResource}.
*
* @author volsch
*/
public interface CustomRemoteSubscriptionResourceRepository
{
@RestResource( exported = false )
@Nonnull
@PreAuthorize( "permitAll()" )
Optional<RemoteSubscriptionResource> findByIdCached( @Nonnull UUID id );
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,8 @@
@CacheConfig( cacheManager = "metadataCacheManager", cacheNames = "remoteSubscriptionResource" )
@RepositoryRestResource
@PreAuthorize( "hasRole('ADMINISTRATION')" )
public interface RemoteSubscriptionResourceRepository extends JpaRepository<RemoteSubscriptionResource, UUID>, QuerydslPredicateExecutor<RemoteSubscriptionResource>
public interface RemoteSubscriptionResourceRepository extends JpaRepository<RemoteSubscriptionResource, UUID>, QuerydslPredicateExecutor<RemoteSubscriptionResource>, CustomRemoteSubscriptionResourceRepository
{
@RestResource( exported = false )
@Query( "SELECT r FROM #{#entityName} r JOIN FETCH r.remoteSubscription s WHERE r.id=:id" )
@Nonnull
@Cacheable( key = "#a0" )
@PreAuthorize( "permitAll()" )
Optional<RemoteSubscriptionResource> findByIdCached( @Param( "id" ) @Nonnull UUID id );

@RestResource( exported = false )
@Query( "SELECT r FROM #{#entityName} r JOIN FETCH r.remoteSubscription s WHERE s=:subscription AND r.fhirResourceType=:fhirResourceType ORDER BY r.id" )
@Nonnull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ public Optional<ExecutableScriptInfo> findInfo( @Nullable ExecutableScript execu
}
Hibernate.initialize( es.getOverrideArguments() );
Hibernate.initialize( es.getScript().getArguments() );
Hibernate.initialize( es.getScript().getVariables() );

final ScriptSource scriptSource = entityManager.createQuery( "SELECT ss FROM ScriptSource ss WHERE ss.script=:script AND :fhirVersion MEMBER OF ss.fhirVersions", ScriptSource.class )
.setParameter( "script", es.getScript() ).setParameter( "fhirVersion", fhirVersion ).getResultList().stream().findFirst().orElse( null );
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
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.RemoteSubscriptionResource;
import org.dhis2.fhir.adapter.fhir.metadata.repository.CustomRemoteSubscriptionResourceRepository;
import org.hibernate.Hibernate;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Nonnull;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.Optional;
import java.util.UUID;

/**
* Implementation of {@link CustomRemoteSubscriptionResourceRepository}.
*
* @author volsch
*/
public class CustomRemoteSubscriptionResourceRepositoryImpl implements CustomRemoteSubscriptionResourceRepository
{
@PersistenceContext
private EntityManager entityManager;

public CustomRemoteSubscriptionResourceRepositoryImpl( @Nonnull EntityManager entityManager )
{
this.entityManager = entityManager;
}

@Nonnull
@Override
@Cacheable( key = "#a0", cacheManager = "metadataCacheManager", cacheNames = "remoteSubscriptionResource" )
@Transactional( readOnly = true )
public Optional<RemoteSubscriptionResource> findByIdCached( @Nonnull UUID id )
{
final RemoteSubscriptionResource rsr = entityManager.find( RemoteSubscriptionResource.class, id );
if ( rsr == null )
{
return Optional.empty();
}

Hibernate.initialize( rsr.getRemoteSubscription().getFhirEndpoint().getHeaders() );
return Optional.of( rsr );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ protected List<? extends IBaseResource> findHierarchy( @Nullable IBaseReference
{
throw new TransformerMappingException( "FHIR client cannot be created without having a remote request." );
}
final RemoteSubscriptionResource subscriptionResource = subscriptionResourceRepository.findById( resourceId )
final RemoteSubscriptionResource subscriptionResource = subscriptionResourceRepository.findByIdCached( resourceId )
.orElseThrow( () -> new TransformerMappingException( "Could not find remote subscription resource with ID " + resourceId ) );

final FhirContext fhirContext = remoteFhirRepository.findFhirContext( context.getFhirRequest().getVersion() )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ public IBaseResource getResource( @Nullable IBaseReference reference, @Nullable
{
throw new TransformerMappingException( "FHIR client cannot be created without having a remote request." );
}
final RemoteSubscriptionResource subscriptionResource = subscriptionResourceRepository.findById( resourceId )
final RemoteSubscriptionResource subscriptionResource = subscriptionResourceRepository.findByIdCached( resourceId )
.orElseThrow( () -> new TransformerMappingException( "Could not find remote subscription resource with ID " + resourceId ) );

final FhirContext fhirContext = remoteFhirRepository.findFhirContext( context.getFhirRequest().getVersion() )
Expand Down

0 comments on commit e4f01f9

Please sign in to comment.