summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/dev/dnpm/etl/processor/pseudonym/GpasPseudonymGenerator.java112
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/config/AppConfiguration.kt79
2 files changed, 88 insertions, 103 deletions
diff --git a/src/main/java/dev/dnpm/etl/processor/pseudonym/GpasPseudonymGenerator.java b/src/main/java/dev/dnpm/etl/processor/pseudonym/GpasPseudonymGenerator.java
index c7c07f2..77caa77 100644
--- a/src/main/java/dev/dnpm/etl/processor/pseudonym/GpasPseudonymGenerator.java
+++ b/src/main/java/dev/dnpm/etl/processor/pseudonym/GpasPseudonymGenerator.java
@@ -23,40 +23,17 @@ import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.parser.IParser;
import dev.dnpm.etl.processor.config.GPasConfigProperties;
import org.apache.commons.lang3.StringUtils;
-import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
-import org.apache.hc.client5.http.impl.classic.HttpClients;
-import org.apache.hc.client5.http.impl.io.BasicHttpClientConnectionManager;
-import org.apache.hc.client5.http.socket.ConnectionSocketFactory;
-import org.apache.hc.client5.http.socket.PlainConnectionSocketFactory;
-import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
-import org.apache.hc.core5.http.config.Registry;
-import org.apache.hc.core5.http.config.RegistryBuilder;
import org.hl7.fhir.r4.model.Identifier;
import org.hl7.fhir.r4.model.Parameters;
import org.hl7.fhir.r4.model.Parameters.ParametersParameterComponent;
import org.hl7.fhir.r4.model.StringType;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.*;
-import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.retry.support.RetryTemplate;
import org.springframework.web.client.RestTemplate;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.TrustManagerFactory;
-import java.io.BufferedInputStream;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.security.KeyManagementException;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-
public class GpasPseudonymGenerator implements Generator {
private final static FhirContext r4Context = FhirContext.forR4();
@@ -68,33 +45,13 @@ public class GpasPseudonymGenerator implements Generator {
private final RestTemplate restTemplate;
- private SSLContext customSslContext;
-
public GpasPseudonymGenerator(GPasConfigProperties gpasCfg, RetryTemplate retryTemplate, RestTemplate restTemplate) {
this.retryTemplate = retryTemplate;
+ this.restTemplate = restTemplate;
this.gPasUrl = gpasCfg.getUri();
this.psnTargetDomain = gpasCfg.getTarget();
httpHeader = getHttpHeaders(gpasCfg.getUsername(), gpasCfg.getPassword());
- try {
- if (StringUtils.isNotBlank(gpasCfg.getSslCaLocation())) {
- customSslContext = getSslContext(gpasCfg.getSslCaLocation());
- log.warn(String.format("%s has been initialized with SSL certificate %s. This is deprecated in favor of including Root CA.",
- this.getClass().getName(), gpasCfg.getSslCaLocation()));
-
- if (customSslContext == null) {
- this.restTemplate = restTemplate;
- } else {
- this.restTemplate = getCustomRestTemplate();
- }
- } else {
- this.restTemplate = restTemplate;
- }
- } catch (IOException | KeyManagementException | KeyStoreException | CertificateException |
- NoSuchAlgorithmException e) {
- throw new RuntimeException(e);
- }
-
log.debug(String.format("%s has been initialized", this.getClass().getName()));
}
@@ -104,7 +61,7 @@ public class GpasPseudonymGenerator implements Generator {
var gPasRequestBody = getGpasRequestBody(id);
var responseEntity = getGpasPseudonym(gPasRequestBody);
var gPasPseudonymResult = (Parameters) r4Context.newJsonParser()
- .parseResource(responseEntity.getBody());
+ .parseResource(responseEntity.getBody());
return unwrapPseudonym(gPasPseudonymResult);
}
@@ -118,9 +75,9 @@ public class GpasPseudonymGenerator implements Generator {
}
final var identifier = (Identifier) parameters.get().getPart().stream()
- .filter(a -> a.getName().equals("pseudonym"))
- .findFirst()
- .orElseGet(ParametersParameterComponent::new).getValue();
+ .filter(a -> a.getName().equals("pseudonym"))
+ .findFirst()
+ .orElseGet(ParametersParameterComponent::new).getValue();
// pseudonym
return sanitizeValue(identifier.getValue());
@@ -149,8 +106,8 @@ public class GpasPseudonymGenerator implements Generator {
try {
responseEntity = retryTemplate.execute(
- ctx -> restTemplate.exchange(gPasUrl, HttpMethod.POST, requestEntity,
- String.class));
+ ctx -> restTemplate.exchange(gPasUrl, HttpMethod.POST, requestEntity,
+ String.class));
if (responseEntity.getStatusCode().is2xxSuccessful()) {
log.debug("API request succeeded. Response: {}", responseEntity.getStatusCode());
@@ -162,16 +119,16 @@ public class GpasPseudonymGenerator implements Generator {
return responseEntity;
} catch (Exception unexpected) {
throw new PseudonymRequestFailed(
- "API request due unexpected error unsuccessful gPas unsuccessful.", unexpected);
+ "API request due unexpected error unsuccessful gPas unsuccessful.", unexpected);
}
}
protected String getGpasRequestBody(String id) {
var requestParameters = new Parameters();
requestParameters.addParameter().setName("target")
- .setValue(new StringType().setValue(psnTargetDomain));
+ .setValue(new StringType().setValue(psnTargetDomain));
requestParameters.addParameter().setName("original")
- .setValue(new StringType().setValue(id));
+ .setValue(new StringType().setValue(id));
final IParser iParser = r4Context.newJsonParser();
return iParser.encodeResourceToString(requestParameters);
}
@@ -188,53 +145,4 @@ public class GpasPseudonymGenerator implements Generator {
headers.setBasicAuth(gPasUserName, gPasPassword);
return headers;
}
-
- /**
- * Read SSL root certificate and return SSLContext
- *
- * @param certificateLocation file location to root certificate (PEM)
- * @return initialized SSLContext
- * @throws IOException file cannot be read
- * @throws CertificateException in case we have an invalid certificate of type X.509
- * @throws KeyStoreException keystore cannot be initialized
- * @throws NoSuchAlgorithmException missing trust manager algorithmus
- * @throws KeyManagementException key management failed at init SSLContext
- */
- @Nullable
- protected SSLContext getSslContext(String certificateLocation)
- throws IOException, CertificateException, KeyStoreException, KeyManagementException, NoSuchAlgorithmException {
-
- KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
-
- FileInputStream fis = new FileInputStream(certificateLocation);
- X509Certificate ca = (X509Certificate) CertificateFactory.getInstance("X.509")
- .generateCertificate(new BufferedInputStream(fis));
-
- ks.load(null, null);
- ks.setCertificateEntry(Integer.toString(1), ca);
-
- TrustManagerFactory tmf = TrustManagerFactory.getInstance(
- TrustManagerFactory.getDefaultAlgorithm());
- tmf.init(ks);
-
- SSLContext sslContext = SSLContext.getInstance("TLS");
- sslContext.init(null, tmf.getTrustManagers(), null);
-
- return sslContext;
- }
-
- protected RestTemplate getCustomRestTemplate() {
- final var sslsf = new SSLConnectionSocketFactory(customSslContext);
- final Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
- .register("https", sslsf).register("http", new PlainConnectionSocketFactory()).build();
-
- final BasicHttpClientConnectionManager connectionManager = new BasicHttpClientConnectionManager(
- socketFactoryRegistry);
- final CloseableHttpClient httpClient = HttpClients.custom()
- .setConnectionManager(connectionManager).build();
-
- final HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(
- httpClient);
- return new RestTemplate(requestFactory);
- }
}
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/config/AppConfiguration.kt b/src/main/kotlin/dev/dnpm/etl/processor/config/AppConfiguration.kt
index 4fa3bf0..2970b4d 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/config/AppConfiguration.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/config/AppConfiguration.kt
@@ -20,7 +20,10 @@
package dev.dnpm.etl.processor.config
import com.fasterxml.jackson.databind.ObjectMapper
-import dev.dnpm.etl.processor.monitoring.*
+import dev.dnpm.etl.processor.monitoring.ConnectionCheckResult
+import dev.dnpm.etl.processor.monitoring.ConnectionCheckService
+import dev.dnpm.etl.processor.monitoring.GPasConnectionCheckService
+import dev.dnpm.etl.processor.monitoring.ReportService
import dev.dnpm.etl.processor.pseudonym.AnonymizingGenerator
import dev.dnpm.etl.processor.pseudonym.Generator
import dev.dnpm.etl.processor.pseudonym.GpasPseudonymGenerator
@@ -29,12 +32,19 @@ import dev.dnpm.etl.processor.services.TokenRepository
import dev.dnpm.etl.processor.services.TokenService
import dev.dnpm.etl.processor.services.Transformation
import dev.dnpm.etl.processor.services.TransformationService
+import org.apache.hc.client5.http.impl.classic.HttpClients
+import org.apache.hc.client5.http.impl.io.BasicHttpClientConnectionManager
+import org.apache.hc.client5.http.socket.ConnectionSocketFactory
+import org.apache.hc.client5.http.socket.PlainConnectionSocketFactory
+import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory
+import org.apache.hc.core5.http.config.RegistryBuilder
import org.slf4j.LoggerFactory
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
+import org.springframework.http.client.HttpComponentsClientHttpRequestFactory
import org.springframework.retry.RetryCallback
import org.springframework.retry.RetryContext
import org.springframework.retry.RetryListener
@@ -46,6 +56,13 @@ import org.springframework.security.crypto.password.PasswordEncoder
import org.springframework.security.provisioning.InMemoryUserDetailsManager
import org.springframework.web.client.RestTemplate
import reactor.core.publisher.Sinks
+import java.io.BufferedInputStream
+import java.io.FileInputStream
+import java.security.KeyStore
+import java.security.cert.CertificateFactory
+import java.security.cert.X509Certificate
+import javax.net.ssl.SSLContext
+import javax.net.ssl.TrustManagerFactory
import kotlin.time.Duration.Companion.seconds
import kotlin.time.toJavaDuration
@@ -84,6 +101,66 @@ class AppConfiguration {
@ConditionalOnMissingBean
@Bean
fun gpasPseudonymGeneratorOnDeprecatedProperty(configProperties: GPasConfigProperties, retryTemplate: RetryTemplate, restTemplate: RestTemplate): Generator {
+ fun getSslContext(certificateLocation: String): SSLContext? {
+ val ks = KeyStore.getInstance(KeyStore.getDefaultType())
+
+ val fis = FileInputStream(certificateLocation)
+ val ca = CertificateFactory.getInstance("X.509")
+ .generateCertificate(BufferedInputStream(fis)) as X509Certificate
+
+ ks.load(null, null)
+ ks.setCertificateEntry(1.toString(), ca)
+
+ val tmf = TrustManagerFactory.getInstance(
+ TrustManagerFactory.getDefaultAlgorithm()
+ )
+ tmf.init(ks)
+
+ val sslContext = SSLContext.getInstance("TLS")
+ sslContext.init(null, tmf.trustManagers, null)
+
+ return sslContext
+ }
+
+ fun getCustomRestTemplate(customSslContext: SSLContext): RestTemplate {
+ val sslsf = SSLConnectionSocketFactory(customSslContext)
+ val socketFactoryRegistry = RegistryBuilder.create<ConnectionSocketFactory>()
+ .register("https", sslsf).register("http", PlainConnectionSocketFactory()).build()
+
+ val connectionManager = BasicHttpClientConnectionManager(
+ socketFactoryRegistry
+ )
+ val httpClient = HttpClients.custom()
+ .setConnectionManager(connectionManager).build()
+
+ val requestFactory = HttpComponentsClientHttpRequestFactory(
+ httpClient
+ )
+ return RestTemplate(requestFactory)
+ }
+
+ try {
+ if (!configProperties.sslCaLocation.isNullOrBlank()) {
+ val customSslContext = getSslContext(configProperties.sslCaLocation)
+ logger.warn(
+ String.format(
+ "%s has been initialized with SSL certificate %s. This is deprecated in favor of including Root CA.",
+ this.javaClass.name, configProperties.sslCaLocation
+ )
+ )
+
+ if (customSslContext != null) {
+ return GpasPseudonymGenerator(
+ configProperties,
+ retryTemplate,
+ getCustomRestTemplate(customSslContext)
+ )
+ }
+ }
+ } catch (e: Exception) {
+ throw RuntimeException(e)
+ }
+
return GpasPseudonymGenerator(configProperties, retryTemplate, restTemplate)
}