Skip to content

Commit

Permalink
fixes proxy config for standalone validator
Browse files Browse the repository at this point in the history
  • Loading branch information
hhund committed Jun 21, 2024
1 parent d80a461 commit 395bbd6
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -367,4 +368,11 @@ public ErrorLogger errorLogger()
{
return new ErrorLogger(api.getMailService(), sendValidationFailedMail, sendProcessFailedMail);
}

// for validation config
@Bean
public ProxyConfig proxyConfig()
{
return api.getProxyConfig();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
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;
import java.util.Arrays;
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;
Expand Down Expand Up @@ -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
{
Expand Down Expand Up @@ -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<String> proxyNoProxy;

@Autowired
private ValidationPackageManager packageManager;

Expand All @@ -86,15 +107,15 @@ 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)
.disable(MapperFeature.AUTO_DETECT_FIELDS).disable(MapperFeature.AUTO_DETECT_SETTERS).build();
}

@Bean
public FhirContext getFhirContext()
public FhirContext fhirContext()
{
FhirContext context = FhirContext.forR4();
HapiLocalizer localizer = new HapiLocalizer()
Expand All @@ -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<String> 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);
}
}

Expand Down

0 comments on commit 395bbd6

Please sign in to comment.