Skip to content

Commit adbfbbb

Browse files
committed
Merge remote-tracking branch 'origin/issue/372_FHIR_Validation_Service'
into develop_2
2 parents d017019 + 9711a43 commit adbfbbb

File tree

13 files changed

+241
-5
lines changed

13 files changed

+241
-5
lines changed

dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/ProcessPluginApiFactory.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import dev.dsf.bpe.v2.service.ReadAccessHelper;
2525
import dev.dsf.bpe.v2.service.TargetProvider;
2626
import dev.dsf.bpe.v2.service.TaskHelper;
27+
import dev.dsf.bpe.v2.service.ValidationServiceProvider;
2728
import dev.dsf.bpe.v2.service.process.ProcessAuthorizationHelper;
2829

2930
public class ProcessPluginApiFactory implements Supplier<ProcessPluginApi>
@@ -52,6 +53,7 @@ public ProcessPluginApi get()
5253
fromParent(ObjectMapper.class), fromParent(OrganizationProvider.class),
5354
fromParent(ProcessAuthorizationHelper.class), fromParent(QuestionnaireResponseHelper.class),
5455
fromParent(ReadAccessHelper.class), fromParent(TaskHelper.class), fromParent(CompressionService.class),
55-
fromParent(CryptoService.class), fromParent(TargetProvider.class), fromParent(DataLogger.class));
56+
fromParent(CryptoService.class), fromParent(TargetProvider.class), fromParent(DataLogger.class),
57+
fromParent(ValidationServiceProvider.class));
5658
}
5759
}

dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/ProcessPluginApiImpl.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import dev.dsf.bpe.v2.service.ReadAccessHelper;
2424
import dev.dsf.bpe.v2.service.TargetProvider;
2525
import dev.dsf.bpe.v2.service.TaskHelper;
26+
import dev.dsf.bpe.v2.service.ValidationServiceProvider;
2627
import dev.dsf.bpe.v2.service.process.ProcessAuthorizationHelper;
2728

2829
public class ProcessPluginApiImpl implements ProcessPluginApi, InitializingBean
@@ -47,6 +48,7 @@ public class ProcessPluginApiImpl implements ProcessPluginApi, InitializingBean
4748
private final CryptoService cryptoService;
4849
private final TargetProvider targetProvider;
4950
private final DataLogger dataLogger;
51+
private final ValidationServiceProvider validationServiceProvider;
5052

5153
public ProcessPluginApiImpl(ProcessPluginDefinition processPluginDefinition, ProxyConfig proxyConfig,
5254
EndpointProvider endpointProvider, FhirContext fhirContext, DsfClientProvider dsfClientProvider,
@@ -56,7 +58,7 @@ public ProcessPluginApiImpl(ProcessPluginDefinition processPluginDefinition, Pro
5658
ProcessAuthorizationHelper processAuthorizationHelper,
5759
QuestionnaireResponseHelper questionnaireResponseHelper, ReadAccessHelper readAccessHelper,
5860
TaskHelper taskHelper, CompressionService compressionService, CryptoService cryptoService,
59-
TargetProvider targetProvider, DataLogger dataLogger)
61+
TargetProvider targetProvider, DataLogger dataLogger, ValidationServiceProvider validationServiceProvider)
6062
{
6163
this.processPluginDefinition = processPluginDefinition;
6264
this.proxyConfig = proxyConfig;
@@ -78,6 +80,7 @@ public ProcessPluginApiImpl(ProcessPluginDefinition processPluginDefinition, Pro
7880
this.cryptoService = cryptoService;
7981
this.targetProvider = targetProvider;
8082
this.dataLogger = dataLogger;
83+
this.validationServiceProvider = validationServiceProvider;
8184
}
8285

8386
@Override
@@ -103,6 +106,7 @@ public void afterPropertiesSet() throws Exception
103106
Objects.requireNonNull(cryptoService, "cryptoService");
104107
Objects.requireNonNull(targetProvider, "targetProvider");
105108
Objects.requireNonNull(dataLogger, "dataLogger");
109+
Objects.requireNonNull(validationServiceProvider, "validationServiceProvider");
106110
}
107111

108112
@Override
@@ -224,4 +228,10 @@ public DataLogger getDataLogger()
224228
{
225229
return dataLogger;
226230
}
231+
232+
@Override
233+
public ValidationServiceProvider getValidationServiceProvider()
234+
{
235+
return validationServiceProvider;
236+
}
227237
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package dev.dsf.bpe.v2.service;
2+
3+
import java.util.List;
4+
import java.util.Objects;
5+
import java.util.Optional;
6+
import java.util.function.Predicate;
7+
8+
import org.hl7.fhir.r4.model.Bundle;
9+
import org.hl7.fhir.r4.model.Resource;
10+
import org.slf4j.Logger;
11+
import org.slf4j.LoggerFactory;
12+
import org.springframework.beans.factory.InitializingBean;
13+
14+
import ca.uhn.fhir.context.FhirContext;
15+
import ca.uhn.fhir.validation.ValidationResult;
16+
import dev.dsf.bpe.v2.service.validation.FhirPackageIdentifier;
17+
import dev.dsf.bpe.v2.service.validation.ValidationService;
18+
19+
public class ValidationServiceProviderImpl implements ValidationServiceProvider, InitializingBean
20+
{
21+
private static final Logger logger = LoggerFactory.getLogger(ValidationServiceProviderImpl.class);
22+
23+
private final boolean enabled;
24+
private final FhirContext fhirContext;
25+
26+
public ValidationServiceProviderImpl(boolean enabled, FhirContext fhirContext)
27+
{
28+
this.enabled = enabled;
29+
this.fhirContext = fhirContext;
30+
}
31+
32+
@Override
33+
public void afterPropertiesSet() throws Exception
34+
{
35+
Objects.requireNonNull(fhirContext, "fhirContext");
36+
}
37+
38+
@Override
39+
public Optional<ValidationService> getValidationService(Predicate<FhirPackageIdentifier> filter,
40+
FhirPackageIdentifier... identifiers)
41+
{
42+
if (!enabled)
43+
return Optional.empty();
44+
else
45+
{
46+
// TODO implement validation, add needed HAPI dependencies
47+
48+
return Optional.of(new ValidationService()
49+
{
50+
@Override
51+
public Bundle validateEntries(Bundle bundle)
52+
{
53+
logger.warn("Bundle validation not implemented, returning bundle as is");
54+
55+
return bundle;
56+
}
57+
58+
@Override
59+
public ValidationResult validate(Resource resource, String profileUrl)
60+
{
61+
return validate(resource);
62+
}
63+
64+
@Override
65+
public ValidationResult validate(Resource resource)
66+
{
67+
logger.warn(
68+
"Resource validation not implemented, returning successful validation result without messages");
69+
70+
return new ValidationResult(fhirContext, List.of());
71+
}
72+
});
73+
}
74+
}
75+
}

dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/spring/ApiServiceConfig.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import dev.dsf.bpe.api.config.BpeProxyConfig;
1818
import dev.dsf.bpe.api.config.DsfClientConfig;
1919
import dev.dsf.bpe.api.config.FhirClientConfigs;
20+
import dev.dsf.bpe.api.config.FhirValidationConfig;
2021
import dev.dsf.bpe.api.listener.ListenerFactory;
2122
import dev.dsf.bpe.api.listener.ListenerFactoryImpl;
2223
import dev.dsf.bpe.api.service.BpeMailService;
@@ -66,6 +67,8 @@
6667
import dev.dsf.bpe.v2.service.TargetProviderImpl;
6768
import dev.dsf.bpe.v2.service.TaskHelper;
6869
import dev.dsf.bpe.v2.service.TaskHelperImpl;
70+
import dev.dsf.bpe.v2.service.ValidationServiceProvider;
71+
import dev.dsf.bpe.v2.service.ValidationServiceProviderImpl;
6972
import dev.dsf.bpe.v2.service.detector.CombinedDetectors;
7073
import dev.dsf.bpe.v2.service.detector.NdJsonDetector;
7174
import dev.dsf.bpe.v2.service.process.ProcessAuthorizationHelper;
@@ -90,6 +93,9 @@ public class ApiServiceConfig
9093
@Autowired
9194
private BpeProxyConfig proxyConfig;
9295

96+
@Autowired
97+
private FhirValidationConfig validationConfig;
98+
9399
@Autowired
94100
private BuildInfoProvider buildInfoProvider;
95101

@@ -306,4 +312,10 @@ public DataLogger dataLogger()
306312
{
307313
return new DataLoggerImpl(fhirContext());
308314
}
315+
316+
@Bean
317+
public ValidationServiceProvider validationServiceProvider()
318+
{
319+
return new ValidationServiceProviderImpl(validationConfig.isEnabled(), fhirContext());
320+
}
309321
}

dsf-bpe/dsf-bpe-process-api-v2/src/main/java/dev/dsf/bpe/v2/ProcessPluginApi.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import dev.dsf.bpe.v2.service.ReadAccessHelper;
2323
import dev.dsf.bpe.v2.service.TargetProvider;
2424
import dev.dsf.bpe.v2.service.TaskHelper;
25+
import dev.dsf.bpe.v2.service.ValidationServiceProvider;
2526
import dev.dsf.bpe.v2.service.process.ProcessAuthorizationHelper;
2627
import dev.dsf.bpe.v2.variables.Variables;
2728

@@ -72,4 +73,6 @@ public interface ProcessPluginApi
7273
TargetProvider getTargetProvider();
7374

7475
DataLogger getDataLogger();
76+
77+
ValidationServiceProvider getValidationServiceProvider();
7578
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package dev.dsf.bpe.v2.service;
2+
3+
import java.util.Optional;
4+
import java.util.function.Predicate;
5+
6+
import dev.dsf.bpe.v2.service.validation.FhirPackageIdentifier;
7+
import dev.dsf.bpe.v2.service.validation.ValidationService;
8+
9+
public interface ValidationServiceProvider
10+
{
11+
/**
12+
* Returns a {@link ValidationService} configured for the given FHIR package <b>identifiers</b> and their
13+
* dependencies.
14+
*
15+
* @param identifiers
16+
* not <code>null</code>, not empty
17+
* @return {@link Optional#empty()} if resource validation is disabled for the DSF instance
18+
*/
19+
default Optional<ValidationService> getValidationService(FhirPackageIdentifier... identifiers)
20+
{
21+
return getValidationService(_ -> true, identifiers);
22+
}
23+
24+
/**
25+
* Returns a {@link ValidationService} configured for the given FHIR package <b>identifiers</b> and their
26+
* dependencies. Excludes packages when the given <b>filter</b> returns <code>false</code>.
27+
*
28+
* @param filter
29+
* not <code>null</code>, packages are only included if allowed by this filter
30+
* @param identifiers
31+
* not <code>null</code>, not empty
32+
* @return {@link Optional#empty()} if resource validation is disabled for the DSF instance
33+
*/
34+
Optional<ValidationService> getValidationService(Predicate<FhirPackageIdentifier> filter,
35+
FhirPackageIdentifier... identifiers);
36+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package dev.dsf.bpe.v2.service.validation;
2+
3+
public record FhirPackageIdentifier(String name, String version)
4+
{
5+
@Override
6+
public String toString()
7+
{
8+
return name + "|" + version;
9+
}
10+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package dev.dsf.bpe.v2.service.validation;
2+
3+
import org.hl7.fhir.r4.model.Bundle;
4+
import org.hl7.fhir.r4.model.OperationOutcome;
5+
import org.hl7.fhir.r4.model.Resource;
6+
7+
import ca.uhn.fhir.validation.ValidationResult;
8+
9+
public interface ValidationService
10+
{
11+
/**
12+
* Validates against profiles self reported by the given <b>resource</b>.
13+
*
14+
* @param resource
15+
* not <code>null</code>
16+
* @return validation results
17+
*/
18+
ValidationResult validate(Resource resource);
19+
20+
/**
21+
* Validates the given <b>resource</b> against the given <b>profileUrl</b>.
22+
*
23+
* @param resource
24+
* not <code>null</code>
25+
* @param profileUrl
26+
* not <code>null</code>, not blank
27+
* @return validation results
28+
*/
29+
ValidationResult validate(Resource resource, String profileUrl);
30+
31+
/**
32+
* Validates all bundle entries with a <code>entry.resource</code> against self reported profiles. Validation result
33+
* is added as a {@link OperationOutcome} resource to the corresponding <code>entry.response.outcome</code>
34+
* property.
35+
*
36+
* @param bundle
37+
* not <code>null</code>
38+
* @return given bundle with added <code>entry.response.outcome</code> properties
39+
*/
40+
Bundle validateEntries(Bundle bundle);
41+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package dev.dsf.bpe.api.config;
2+
3+
public interface FhirValidationConfig
4+
{
5+
boolean isEnabled();
6+
}

dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/plugin/ProcessPluginApiFactory.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import dev.dsf.bpe.api.config.BpeProxyConfig;
1919
import dev.dsf.bpe.api.config.DsfClientConfig;
2020
import dev.dsf.bpe.api.config.FhirClientConfigs;
21+
import dev.dsf.bpe.api.config.FhirValidationConfig;
2122
import dev.dsf.bpe.api.plugin.ProcessPluginApiBuilder;
2223
import dev.dsf.bpe.api.plugin.ProcessPluginFactory;
2324
import dev.dsf.bpe.api.service.BpeMailService;
@@ -32,21 +33,24 @@ public class ProcessPluginApiFactory implements InitializingBean
3233
private final DsfClientConfig dsfClientConfig;
3334
private final FhirClientConfigs fhirClientConfigs;
3435
private final BpeProxyConfig bpeProxyConfig;
36+
private final FhirValidationConfig fhirValidationConfig;
3537
private final BuildInfoProvider buildInfoProvider;
3638
private final BpeMailService bpeMailService;
3739
private final BpeOidcClientProvider bpeOidcClientProvider;
3840
private final ProcessPluginApiClassLoaderFactory classLoaderFactory;
3941
private final String serverBaseUrl;
4042

4143
public ProcessPluginApiFactory(ConfigurableEnvironment environment, DsfClientConfig dsfClientConfig,
42-
FhirClientConfigs fhirClientConfigs, BpeProxyConfig bpeProxyConfig, BuildInfoProvider buildInfoProvider,
44+
FhirClientConfigs fhirClientConfigs, BpeProxyConfig bpeProxyConfig,
45+
FhirValidationConfig fhirValidationConfig, BuildInfoProvider buildInfoProvider,
4346
BpeMailService bpeMailService, BpeOidcClientProvider bpeOidcClientProvider,
4447
ProcessPluginApiClassLoaderFactory classLoaderFactory, String serverBaseUrl)
4548
{
4649
this.environment = environment;
4750
this.dsfClientConfig = dsfClientConfig;
4851
this.fhirClientConfigs = fhirClientConfigs;
4952
this.bpeProxyConfig = bpeProxyConfig;
53+
this.fhirValidationConfig = fhirValidationConfig;
5054
this.buildInfoProvider = buildInfoProvider;
5155
this.bpeMailService = bpeMailService;
5256
this.bpeOidcClientProvider = bpeOidcClientProvider;
@@ -61,6 +65,7 @@ public void afterPropertiesSet() throws Exception
6165
Objects.requireNonNull(dsfClientConfig, "dsfClientConfig");
6266
Objects.requireNonNull(fhirClientConfigs, "fhirClientConfigs");
6367
Objects.requireNonNull(bpeProxyConfig, "bpeProxyConfig");
68+
Objects.requireNonNull(fhirValidationConfig, "fhirValidationConfig");
6469
Objects.requireNonNull(buildInfoProvider, "buildInfoProvider");
6570
Objects.requireNonNull(bpeMailService, "bpeMailService");
6671
Objects.requireNonNull(bpeOidcClientProvider, "bpeOidcClientProvider");
@@ -98,6 +103,7 @@ private ApplicationContext createApiApplicationContext(int apiVersion, ClassLoad
98103
factory.registerSingleton("dsfClientConfig", dsfClientConfig);
99104
factory.registerSingleton("fhirClientConfigs", fhirClientConfigs);
100105
factory.registerSingleton("bpeProxyConfig", bpeProxyConfig);
106+
factory.registerSingleton("fhirValidationConfig", fhirValidationConfig);
101107
factory.registerSingleton("buildInfoReader", buildInfoProvider);
102108
factory.registerSingleton("bpeMailService", bpeMailService);
103109
factory.registerSingleton("bpeOidcClientProvider", bpeOidcClientProvider);

0 commit comments

Comments
 (0)