diff --git a/codex-process-data-transfer/pom.xml b/codex-process-data-transfer/pom.xml
index edab793..5deab4c 100644
--- a/codex-process-data-transfer/pom.xml
+++ b/codex-process-data-transfer/pom.xml
@@ -24,7 +24,7 @@
org.springframework
spring-web
- 6.0.11
+ 6.1.6
provided
@@ -181,7 +181,7 @@
commons-codec,commons-io,crypto-utils,jakarta.activation,jakarta.annotation-api,jakarta.ws.rs-api,jakarta.xml.bind-api,commons-compress,commons-lang3,commons-text,
httpclient,httpcore,log4j-api,log4j-core,log4j-slf4j2-impl,bcpkix-jdk18on,bcprov-jdk18on,bcutil-jdk18on,ucum,hk2-api,hk2-locator,hk2-utils,osgi-resource-locator,
aopalliance-repackaged,jakarta.inject-api,jersey-apache-connector,jersey-client,jersey-common,jersey-entity-filtering,jersey-hk2,jersey-media-jaxb,jersey-media-json-jackson,
- dsf-bpe-process-api-v1,dsf-fhir-auth,dsf-fhir-rest-adapter,dsf-fhir-validation,dsf-openehr-model,jcl-over-slf4j,
+ dsf-bpe-process-api-v1,dsf-fhir-auth,dsf-fhir-rest-adapter,dsf-fhir-validation,dsf-openehr-model,jcl-over-slf4j,jackson-module-jakarta-xmlbind-annotations,
slf4j-api,spring-aop,spring-beans,spring-context,spring-core,spring-expression,spring-jcl,thymeleaf,unbescape,xpp3,xpp3_xpath
diff --git a/codex-process-data-transfer/src/main/java/de/netzwerk_universitaetsmedizin/codex/processes/data_transfer/spring/config/TransferDataConfig.java b/codex-process-data-transfer/src/main/java/de/netzwerk_universitaetsmedizin/codex/processes/data_transfer/spring/config/TransferDataConfig.java
index 6d6266e..4289655 100644
--- a/codex-process-data-transfer/src/main/java/de/netzwerk_universitaetsmedizin/codex/processes/data_transfer/spring/config/TransferDataConfig.java
+++ b/codex-process-data-transfer/src/main/java/de/netzwerk_universitaetsmedizin/codex/processes/data_transfer/spring/config/TransferDataConfig.java
@@ -21,6 +21,7 @@
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.logging.DataLogger;
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.logging.ErrorLogger;
import dev.dsf.bpe.v1.ProcessPluginApi;
+import dev.dsf.bpe.v1.config.ProxyConfig;
import dev.dsf.bpe.v1.documentation.ProcessDocumentation;
@Configuration
@@ -367,4 +368,11 @@ public ErrorLogger errorLogger()
{
return new ErrorLogger(api.getMailService(), sendValidationFailedMail, sendProcessFailedMail);
}
+
+ // for validation config
+ @Bean
+ public ProxyConfig proxyConfig()
+ {
+ return api.getProxyConfig();
+ }
}
diff --git a/codex-process-data-transfer/src/main/java/de/netzwerk_universitaetsmedizin/codex/processes/data_transfer/spring/config/ValidationConfig.java b/codex-process-data-transfer/src/main/java/de/netzwerk_universitaetsmedizin/codex/processes/data_transfer/spring/config/ValidationConfig.java
index 98a5372..cf97626 100644
--- a/codex-process-data-transfer/src/main/java/de/netzwerk_universitaetsmedizin/codex/processes/data_transfer/spring/config/ValidationConfig.java
+++ b/codex-process-data-transfer/src/main/java/de/netzwerk_universitaetsmedizin/codex/processes/data_transfer/spring/config/ValidationConfig.java
@@ -54,7 +54,7 @@
import de.rwh.utils.crypto.CertificateHelper;
import de.rwh.utils.crypto.io.CertificateReader;
import de.rwh.utils.crypto.io.PemIo;
-import dev.dsf.bpe.v1.ProcessPluginApi;
+import dev.dsf.bpe.v1.config.ProxyConfig;
import dev.dsf.bpe.v1.documentation.ProcessDocumentation;
import dev.dsf.fhir.validation.SnapshotGenerator;
import dev.dsf.fhir.validation.ValueSetExpander;
@@ -66,9 +66,6 @@ public class ValidationConfig
{
private static final Logger logger = LoggerFactory.getLogger(ValidationConfig.class);
- @Autowired
- private ProcessPluginApi api;
-
public static enum TerminologyServerConnectionTestStatus
{
OK, NOT_OK, DISABLED
@@ -209,6 +206,9 @@ public static enum TerminologyServerConnectionTestStatus
@Autowired
private ObjectMapper objectMapper;
+ // not using process plugin api to enable reuse of this config class in stand-alone validator
+ @Autowired
+ private ProxyConfig proxyConfig;
@Bean
public ValidationPackageManager validationPackageManager()
@@ -376,11 +376,11 @@ private ValidationPackageClientJersey validationPackageClientJersey()
String proxyUrl = null, proxyUsername = null;
char[] proxyPassword = null;
- if (api.getProxyConfig().isEnabled() && !api.getProxyConfig().isNoProxyUrl(packageServerBaseUrl))
+ if (proxyConfig.isEnabled() && !proxyConfig.isNoProxyUrl(packageServerBaseUrl))
{
- proxyUrl = api.getProxyConfig().getUrl();
- proxyUsername = api.getProxyConfig().getUsername();
- proxyPassword = api.getProxyConfig().getPassword() == null ? null : api.getProxyConfig().getPassword();
+ proxyUrl = proxyConfig.getUrl();
+ proxyUsername = proxyConfig.getUsername();
+ proxyPassword = proxyConfig.getPassword() == null ? null : proxyConfig.getPassword();
}
KeyStore packageClientTrustStore = trustStore("FHIR package client", packageClientTrustCertificates);
@@ -439,11 +439,11 @@ private ValueSetExpansionClient valueSetExpansionClientJersey()
String proxyUrl = null, proxyUsername = null;
char[] proxyPassword = null;
- if (api.getProxyConfig().isEnabled() && !api.getProxyConfig().isNoProxyUrl(valueSetExpansionServerBaseUrl))
+ if (proxyConfig.isEnabled() && !proxyConfig.isNoProxyUrl(valueSetExpansionServerBaseUrl))
{
- proxyUrl = api.getProxyConfig().getUrl();
- proxyUsername = api.getProxyConfig().getUsername();
- proxyPassword = api.getProxyConfig().getPassword() == null ? null : api.getProxyConfig().getPassword();
+ proxyUrl = proxyConfig.getUrl();
+ proxyUsername = proxyConfig.getUsername();
+ proxyPassword = proxyConfig.getPassword() == null ? null : proxyConfig.getPassword();
}
KeyStore valueSetExpansionClientTrustStore = trustStore("ValueSet expansion client",
diff --git a/codex-process-data-transfer/src/main/java/de/netzwerk_universitaetsmedizin/codex/processes/data_transfer/validation/ValidationMain.java b/codex-process-data-transfer/src/main/java/de/netzwerk_universitaetsmedizin/codex/processes/data_transfer/validation/ValidationMain.java
index 048d70a..a807dc9 100644
--- a/codex-process-data-transfer/src/main/java/de/netzwerk_universitaetsmedizin/codex/processes/data_transfer/validation/ValidationMain.java
+++ b/codex-process-data-transfer/src/main/java/de/netzwerk_universitaetsmedizin/codex/processes/data_transfer/validation/ValidationMain.java
@@ -1,6 +1,8 @@
package de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.validation;
import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
@@ -8,6 +10,7 @@
import java.util.List;
import java.util.Locale;
import java.util.Objects;
+import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.hl7.fhir.instance.model.api.IBaseResource;
@@ -36,6 +39,8 @@
import ca.uhn.fhir.validation.ValidationResult;
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.spring.config.ValidationConfig;
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.spring.config.ValidationConfig.TerminologyServerConnectionTestStatus;
+import dev.dsf.bpe.v1.config.ProxyConfig;
+import dev.dsf.bpe.v1.documentation.ProcessDocumentation;
public class ValidationMain implements InitializingBean
{
@@ -73,6 +78,22 @@ public static class TestConfig
@Value("${de.netzwerk.universitaetsmedizin.rdp.validation.output.pretty:true}")
private boolean outputPretty;
+ @ProcessDocumentation(description = "Forward (http/https) proxy url, use *DEV_DSF_BPE_PROXY_NOPROXY* to list domains that do not require a forward proxy", example = "http://proxy.foo:8080")
+ @Value("${de.netzwerk.universitaetsmedizin.rdp.validation.proxy.url:#{null}}")
+ private String proxyUrl;
+
+ @ProcessDocumentation(description = "Forward proxy username", recommendation = "Configure username if proxy requires authentication")
+ @Value("${de.netzwerk.universitaetsmedizin.rdp.validation.proxy.username:#{null}}")
+ private String proxyUsername;
+
+ @ProcessDocumentation(description = "Forward Proxy password", recommendation = "Configure password if proxy requires authentication, use docker secret file to configure using *${env_variable}_FILE*")
+ @Value("${de.netzwerk.universitaetsmedizin.rdp.validation.proxy.password:#{null}}")
+ private char[] proxyPassword;
+
+ @ProcessDocumentation(description = "Forward proxy no-proxy list, entries will match exactly or agianst (one level) sub-domains, if no port is specified - all ports are matched; comma or space separated list, YAML block scalars supported", example = "foo.bar, test.com:8080")
+ @Value("#{'${de.netzwerk.universitaetsmedizin.rdp.validation.proxy.noProxy:}'.trim().split('(,[ ]?)|(\\n)')}")
+ private List proxyNoProxy;
+
@Autowired
private ValidationPackageManager packageManager;
@@ -86,7 +107,7 @@ public static class TestConfig
private ConfigurableEnvironment environment;
@Bean
- public ObjectMapper getObjectMapper()
+ public ObjectMapper objectMapper()
{
return JsonMapper.builder().serializationInclusion(Include.NON_NULL)
.serializationInclusion(Include.NON_EMPTY).disable(MapperFeature.AUTO_DETECT_CREATORS)
@@ -94,7 +115,7 @@ public ObjectMapper getObjectMapper()
}
@Bean
- public FhirContext getFhirContext()
+ public FhirContext fhirContext()
{
FhirContext context = FhirContext.forR4();
HapiLocalizer localizer = new HapiLocalizer()
@@ -109,11 +130,91 @@ public Locale getLocale()
return context;
}
+ @Bean
+ public ProxyConfig proxyConfig()
+ {
+ return new ProxyConfig()
+ {
+ @Override
+ public boolean isNoProxyUrl(String targetUrl)
+ {
+ if (proxyNoProxy.contains("*"))
+ return true;
+
+ if (targetUrl == null || targetUrl.isBlank())
+ return false;
+
+ try
+ {
+ URI u = new URI(targetUrl);
+
+ String host = u.getHost();
+ if (host == null)
+ {
+ logger.debug("Given targetUrl '{}' is malformed, no host value", targetUrl);
+ return false;
+ }
+
+ String subHost = Stream.of(u.getHost().split("\\.")).skip(1).collect(Collectors.joining("."));
+ int port = u.getPort() == -1 ? getDefaultPort(u.getScheme()) : u.getPort();
+
+ return proxyNoProxy.stream().anyMatch(s -> s.equals(host) || s.equals(host + ":" + port)
+ || s.equals(subHost) || s.equals(subHost + ":" + port));
+ }
+ catch (URISyntaxException e)
+ {
+ logger.debug("Given targetUrl '{}' is malformed: {}", targetUrl, e.getMessage());
+ return false;
+ }
+ }
+
+ private int getDefaultPort(String scheme)
+ {
+ return switch (scheme)
+ {
+ case "http", "ws" -> 80;
+ case "https", "wss" -> 443;
+ default -> throw new IllegalArgumentException("Schema " + scheme + " not supported");
+ };
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return getUrl() != null;
+ }
+
+ @Override
+ public String getUsername()
+ {
+ return proxyUsername;
+ }
+
+ @Override
+ public String getUrl()
+ {
+ return proxyUrl;
+ }
+
+ @Override
+ public char[] getPassword()
+ {
+ return proxyPassword;
+ }
+
+ @Override
+ public List getNoProxyUrls()
+ {
+ return proxyNoProxy;
+ }
+ };
+ }
+
@Bean
public ValidationMain validatorMain()
{
- return new ValidationMain(environment, getFhirContext(), packageManager, validationPackageIdentifiers,
- output, outputPretty, valueSetExpansionClient);
+ return new ValidationMain(environment, fhirContext(), packageManager, validationPackageIdentifiers, output,
+ outputPretty, valueSetExpansionClient);
}
}
diff --git a/codex-processes-ap1-docker-test-setup/docker-compose.yml b/codex-processes-ap1-docker-test-setup/docker-compose.yml
index f40c528..60b98ca 100644
--- a/codex-processes-ap1-docker-test-setup/docker-compose.yml
+++ b/codex-processes-ap1-docker-test-setup/docker-compose.yml
@@ -74,7 +74,7 @@ services:
dic-fhir:
- image: ghcr.io/datasharingframework/fhir:1.5.0
+ image: ghcr.io/datasharingframework/fhir:1.5.1
restart: "no"
ports:
- 127.0.0.1:5000:5000
@@ -136,7 +136,7 @@ services:
- db
- proxy
dic-bpe:
- image: ghcr.io/datasharingframework/bpe:1.5.0
+ image: ghcr.io/datasharingframework/bpe:1.5.1
restart: "no"
ports:
- 127.0.0.1:5003:5003
@@ -232,7 +232,7 @@ services:
dts-fhir:
- image: ghcr.io/datasharingframework/fhir:1.5.0
+ image: ghcr.io/datasharingframework/fhir:1.5.1
restart: "no"
ports:
- 127.0.0.1:5001:5001
@@ -293,7 +293,7 @@ services:
- db
- proxy
dts-bpe:
- image: ghcr.io/datasharingframework/bpe:1.5.0
+ image: ghcr.io/datasharingframework/bpe:1.5.1
restart: "no"
ports:
- 127.0.0.1:5004:5004
@@ -356,7 +356,7 @@ services:
crr-fhir:
- image: ghcr.io/datasharingframework/fhir:1.5.0
+ image: ghcr.io/datasharingframework/fhir:1.5.1
restart: "no"
ports:
- 127.0.0.1:5002:5002
@@ -417,7 +417,7 @@ services:
- db
- proxy
crr-bpe:
- image: ghcr.io/datasharingframework/bpe:1.5.0
+ image: ghcr.io/datasharingframework/bpe:1.5.1
restart: "no"
ports:
- 127.0.0.1:5005:5005
diff --git a/pom.xml b/pom.xml
index c3a6c4e..97842bc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -20,7 +20,7 @@
${project.basedir}
5.1.0
- 1.5.0
+ 1.5.1
Business processes for the NUM RDP project (AP1) as plugins for the Data Sharing Framework.