summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul-Christian Volkmer2024-03-06 10:54:44 +0100
committerGitHub2024-03-06 10:54:44 +0100
commita8e008000ed806eb82184c1390881924bf02b8e8 (patch)
tree2eefcac6d815478175c2976311d633724761b70f
parent67ab0ef2be5c01287feacd3eb604c3d0e627b211 (diff)
parenta9c771aa9950c3d088461fcc3261d689c2d9ff17 (diff)
Merge pull request #54 from CCC-MF/issue_53
Anzeige gPAS Verbindungsstatus
-rw-r--r--src/integrationTest/kotlin/dev/dnpm/etl/processor/web/ConfigControllerTest.kt8
-rw-r--r--src/main/java/dev/dnpm/etl/processor/pseudonym/GpasPseudonymGenerator.java16
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/config/AppConfiguration.kt33
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/config/AppKafkaConfiguration.kt8
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/config/AppRestConfiguration.kt12
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/monitoring/ConnectionCheckService.kt85
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/web/ConfigController.kt57
-rw-r--r--src/main/resources/templates/configs.html7
-rw-r--r--src/main/resources/templates/configs/gPasConnectionAvailable.html19
-rw-r--r--src/main/resources/templates/configs/outputConnectionAvailable.html (renamed from src/main/resources/templates/configs/connectionAvailable.html)8
10 files changed, 205 insertions, 48 deletions
diff --git a/src/integrationTest/kotlin/dev/dnpm/etl/processor/web/ConfigControllerTest.kt b/src/integrationTest/kotlin/dev/dnpm/etl/processor/web/ConfigControllerTest.kt
index 6e6a25e..7fc0121 100644
--- a/src/integrationTest/kotlin/dev/dnpm/etl/processor/web/ConfigControllerTest.kt
+++ b/src/integrationTest/kotlin/dev/dnpm/etl/processor/web/ConfigControllerTest.kt
@@ -19,11 +19,14 @@
package dev.dnpm.etl.processor.web
+import dev.dnpm.etl.processor.config.AppConfiguration
import dev.dnpm.etl.processor.config.AppSecurityConfiguration
import dev.dnpm.etl.processor.monitoring.ConnectionCheckService
+import dev.dnpm.etl.processor.monitoring.RestConnectionCheckService
import dev.dnpm.etl.processor.output.MtbFileSender
import dev.dnpm.etl.processor.pseudonym.Generator
import dev.dnpm.etl.processor.services.RequestProcessor
+import dev.dnpm.etl.processor.services.TokenRepository
import dev.dnpm.etl.processor.services.TransformationService
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
@@ -50,6 +53,7 @@ abstract class MockSink : Sinks.Many<Boolean>
@ContextConfiguration(
classes = [
ConfigController::class,
+ AppConfiguration::class,
AppSecurityConfiguration::class
]
)
@@ -67,7 +71,9 @@ abstract class MockSink : Sinks.Many<Boolean>
MtbFileSender::class,
ConnectionCheckService::class,
RequestProcessor::class,
- TransformationService::class
+ TransformationService::class,
+ TokenRepository::class,
+ RestConnectionCheckService::class
)
class ConfigControllerTest {
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 3d367bc..446bd16 100644
--- a/src/main/java/dev/dnpm/etl/processor/pseudonym/GpasPseudonymGenerator.java
+++ b/src/main/java/dev/dnpm/etl/processor/pseudonym/GpasPseudonymGenerator.java
@@ -67,11 +67,13 @@ public class GpasPseudonymGenerator implements Generator {
private final RetryTemplate retryTemplate;
private final Logger log = LoggerFactory.getLogger(GpasPseudonymGenerator.class);
+ private final RestTemplate restTemplate;
+
private SSLContext customSslContext;
- private RestTemplate restTemplate;
public GpasPseudonymGenerator(GPasConfigProperties gpasCfg, RetryTemplate retryTemplate) {
this.retryTemplate = retryTemplate;
+ this.restTemplate = getRestTemplete();
this.gPasUrl = gpasCfg.getUri();
this.psnTargetDomain = gpasCfg.getTarget();
@@ -139,7 +141,6 @@ public class GpasPseudonymGenerator implements Generator {
HttpEntity<String> requestEntity = new HttpEntity<>(gPasRequestBody, this.httpHeader);
ResponseEntity<String> responseEntity;
- var restTemplate = getRestTemplete();
try {
responseEntity = retryTemplate.execute(
@@ -226,14 +227,8 @@ public class GpasPseudonymGenerator implements Generator {
}
protected RestTemplate getRestTemplete() {
-
- if (restTemplate != null) {
- return restTemplate;
- }
-
if (customSslContext == null) {
- restTemplate = new RestTemplate();
- return restTemplate;
+ return new RestTemplate();
}
final var sslsf = new SSLConnectionSocketFactory(customSslContext);
final Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
@@ -246,7 +241,6 @@ public class GpasPseudonymGenerator implements Generator {
final HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(
httpClient);
- restTemplate = new RestTemplate(requestFactory);
- return restTemplate;
+ 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 8fb9e19..0ae2c2f 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,7 @@
package dev.dnpm.etl.processor.config
import com.fasterxml.jackson.databind.ObjectMapper
-import dev.dnpm.etl.processor.monitoring.ReportService
+import dev.dnpm.etl.processor.monitoring.*
import dev.dnpm.etl.processor.pseudonym.AnonymizingGenerator
import dev.dnpm.etl.processor.pseudonym.Generator
import dev.dnpm.etl.processor.pseudonym.GpasPseudonymGenerator
@@ -44,6 +44,7 @@ import org.springframework.retry.support.RetryTemplateBuilder
import org.springframework.scheduling.annotation.EnableScheduling
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 kotlin.time.Duration.Companion.seconds
import kotlin.time.toJavaDuration
@@ -62,6 +63,11 @@ class AppConfiguration {
private val logger = LoggerFactory.getLogger(AppConfiguration::class.java)
+ @Bean
+ fun restTemplate(): RestTemplate {
+ return RestTemplate()
+ }
+
@ConditionalOnProperty(value = ["app.pseudonymize.generator"], havingValue = "GPAS")
@Bean
fun gpasPseudonymGenerator(configProperties: GPasConfigProperties, retryTemplate: RetryTemplate): Generator {
@@ -142,8 +148,29 @@ class AppConfiguration {
}
@Bean
- fun configsUpdateProducer(): Sinks.Many<Boolean> {
- return Sinks.many().multicast().directBestEffort()
+ fun connectionCheckUpdateProducer(): Sinks.Many<ConnectionCheckResult> {
+ return Sinks.many().multicast().onBackpressureBuffer()
+ }
+
+ @ConditionalOnProperty(value = ["app.pseudonymize.generator"], havingValue = "GPAS")
+ @Bean
+ fun gPasConnectionCheckService(
+ restTemplate: RestTemplate,
+ gPasConfigProperties: GPasConfigProperties,
+ connectionCheckUpdateProducer: Sinks.Many<ConnectionCheckResult>
+ ): ConnectionCheckService {
+ return GPasConnectionCheckService(restTemplate, gPasConfigProperties, connectionCheckUpdateProducer)
+ }
+
+ @ConditionalOnProperty(value = ["app.pseudonymizer"], havingValue = "GPAS")
+ @ConditionalOnMissingBean
+ @Bean
+ fun gPasConnectionCheckServiceOnDeprecatedProperty(
+ restTemplate: RestTemplate,
+ gPasConfigProperties: GPasConfigProperties,
+ connectionCheckUpdateProducer: Sinks.Many<ConnectionCheckResult>
+ ): ConnectionCheckService {
+ return GPasConnectionCheckService(restTemplate, gPasConfigProperties, connectionCheckUpdateProducer)
}
}
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/config/AppKafkaConfiguration.kt b/src/main/kotlin/dev/dnpm/etl/processor/config/AppKafkaConfiguration.kt
index 3799762..80c66d2 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/config/AppKafkaConfiguration.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/config/AppKafkaConfiguration.kt
@@ -21,6 +21,7 @@ package dev.dnpm.etl.processor.config
import com.fasterxml.jackson.databind.ObjectMapper
import dev.dnpm.etl.processor.input.KafkaInputListener
+import dev.dnpm.etl.processor.monitoring.ConnectionCheckResult
import dev.dnpm.etl.processor.monitoring.ConnectionCheckService
import dev.dnpm.etl.processor.monitoring.KafkaConnectionCheckService
import dev.dnpm.etl.processor.output.KafkaMtbFileSender
@@ -105,8 +106,11 @@ class AppKafkaConfiguration {
}
@Bean
- fun connectionCheckService(consumerFactory: ConsumerFactory<String, String>, configsUpdateProducer: Sinks.Many<Boolean>): ConnectionCheckService {
- return KafkaConnectionCheckService(consumerFactory.createConsumer(), configsUpdateProducer)
+ fun kafkaConnectionCheckService(
+ consumerFactory: ConsumerFactory<String, String>,
+ connectionCheckUpdateProducer: Sinks.Many<ConnectionCheckResult>
+ ): ConnectionCheckService {
+ return KafkaConnectionCheckService(consumerFactory.createConsumer(), connectionCheckUpdateProducer)
}
} \ No newline at end of file
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/config/AppRestConfiguration.kt b/src/main/kotlin/dev/dnpm/etl/processor/config/AppRestConfiguration.kt
index eea5724..fc2676b 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/config/AppRestConfiguration.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/config/AppRestConfiguration.kt
@@ -19,6 +19,7 @@
package dev.dnpm.etl.processor.config
+import dev.dnpm.etl.processor.monitoring.ConnectionCheckResult
import dev.dnpm.etl.processor.monitoring.ConnectionCheckService
import dev.dnpm.etl.processor.monitoring.RestConnectionCheckService
import dev.dnpm.etl.processor.output.MtbFileSender
@@ -48,11 +49,6 @@ class AppRestConfiguration {
private val logger = LoggerFactory.getLogger(AppRestConfiguration::class.java)
@Bean
- fun restTemplate(): RestTemplate {
- return RestTemplate()
- }
-
- @Bean
fun restMtbFileSender(
restTemplate: RestTemplate,
restTargetProperties: RestTargetProperties,
@@ -63,12 +59,12 @@ class AppRestConfiguration {
}
@Bean
- fun connectionCheckService(
+ fun restConnectionCheckService(
restTemplate: RestTemplate,
restTargetProperties: RestTargetProperties,
- configsUpdateProducer: Sinks.Many<Boolean>
+ connectionCheckUpdateProducer: Sinks.Many<ConnectionCheckResult>
): ConnectionCheckService {
- return RestConnectionCheckService(restTemplate, restTargetProperties, configsUpdateProducer)
+ return RestConnectionCheckService(restTemplate, restTargetProperties, connectionCheckUpdateProducer)
}
}
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/monitoring/ConnectionCheckService.kt b/src/main/kotlin/dev/dnpm/etl/processor/monitoring/ConnectionCheckService.kt
index 54f25b3..81ad922 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/monitoring/ConnectionCheckService.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/monitoring/ConnectionCheckService.kt
@@ -20,14 +20,21 @@
package dev.dnpm.etl.processor.monitoring
+import dev.dnpm.etl.processor.config.GPasConfigProperties
import dev.dnpm.etl.processor.config.RestTargetProperties
import jakarta.annotation.PostConstruct
import org.apache.kafka.clients.consumer.Consumer
import org.apache.kafka.common.errors.TimeoutException
import org.springframework.beans.factory.annotation.Qualifier
+import org.springframework.http.HttpEntity
+import org.springframework.http.HttpHeaders
+import org.springframework.http.HttpMethod
import org.springframework.http.HttpStatus
+import org.springframework.http.MediaType
+import org.springframework.http.RequestEntity
import org.springframework.scheduling.annotation.Scheduled
import org.springframework.web.client.RestTemplate
+import org.springframework.web.util.UriComponentsBuilder
import reactor.core.publisher.Sinks
import kotlin.time.Duration.Companion.seconds
import kotlin.time.toJavaDuration
@@ -38,11 +45,22 @@ interface ConnectionCheckService {
}
+interface OutputConnectionCheckService : ConnectionCheckService
+
+sealed class ConnectionCheckResult {
+
+ abstract val available: Boolean
+
+ data class KafkaConnectionCheckResult(override val available: Boolean) : ConnectionCheckResult()
+ data class RestConnectionCheckResult(override val available: Boolean) : ConnectionCheckResult()
+ data class GPasConnectionCheckResult(override val available: Boolean) : ConnectionCheckResult()
+}
+
class KafkaConnectionCheckService(
private val consumer: Consumer<String, String>,
- @Qualifier("configsUpdateProducer")
- private val configsUpdateProducer: Sinks.Many<Boolean>
-) : ConnectionCheckService {
+ @Qualifier("connectionCheckUpdateProducer")
+ private val connectionCheckUpdateProducer: Sinks.Many<ConnectionCheckResult>
+) : OutputConnectionCheckService {
private var connectionAvailable: Boolean = false
@@ -55,7 +73,10 @@ class KafkaConnectionCheckService(
} catch (e: TimeoutException) {
false
}
- configsUpdateProducer.emitNext(connectionAvailable, Sinks.EmitFailureHandler.FAIL_FAST)
+ connectionCheckUpdateProducer.emitNext(
+ ConnectionCheckResult.KafkaConnectionCheckResult(connectionAvailable),
+ Sinks.EmitFailureHandler.FAIL_FAST
+ )
}
override fun connectionAvailable(): Boolean {
@@ -67,9 +88,9 @@ class KafkaConnectionCheckService(
class RestConnectionCheckService(
private val restTemplate: RestTemplate,
private val restTargetProperties: RestTargetProperties,
- @Qualifier("configsUpdateProducer")
- private val configsUpdateProducer: Sinks.Many<Boolean>
-) : ConnectionCheckService {
+ @Qualifier("connectionCheckUpdateProducer")
+ private val connectionCheckUpdateProducer: Sinks.Many<ConnectionCheckResult>
+) : OutputConnectionCheckService {
private var connectionAvailable: Boolean = false
@@ -84,7 +105,55 @@ class RestConnectionCheckService(
} catch (e: Exception) {
false
}
- configsUpdateProducer.emitNext(connectionAvailable, Sinks.EmitFailureHandler.FAIL_FAST)
+ connectionCheckUpdateProducer.emitNext(
+ ConnectionCheckResult.RestConnectionCheckResult(connectionAvailable),
+ Sinks.EmitFailureHandler.FAIL_FAST
+ )
+ }
+
+ override fun connectionAvailable(): Boolean {
+ return this.connectionAvailable
+ }
+}
+
+class GPasConnectionCheckService(
+ private val restTemplate: RestTemplate,
+ private val gPasConfigProperties: GPasConfigProperties,
+ @Qualifier("connectionCheckUpdateProducer")
+ private val connectionCheckUpdateProducer: Sinks.Many<ConnectionCheckResult>
+) : ConnectionCheckService {
+
+ private var connectionAvailable: Boolean = false
+
+ @PostConstruct
+ @Scheduled(cron = "0 * * * * *")
+ fun check() {
+ connectionAvailable = try {
+ val uri = UriComponentsBuilder.fromUriString(
+ gPasConfigProperties.uri?.replace("/\$pseudonymizeAllowCreate", "/\$pseudonymize").toString()
+ )
+ .queryParam("target", gPasConfigProperties.target)
+ .queryParam("original", "???")
+ .build().toUri()
+
+ val headers = HttpHeaders()
+ headers.contentType = MediaType.APPLICATION_JSON
+ if (!gPasConfigProperties.username.isNullOrBlank() && !gPasConfigProperties.password.isNullOrBlank()) {
+ headers.setBasicAuth(gPasConfigProperties.username, gPasConfigProperties.password)
+ }
+ restTemplate.exchange(
+ uri,
+ HttpMethod.GET,
+ HttpEntity<Void>(headers),
+ Void::class.java
+ ).statusCode == HttpStatus.OK
+ } catch (e: Exception) {
+ false
+ }
+ connectionCheckUpdateProducer.emitNext(
+ ConnectionCheckResult.GPasConnectionCheckResult(connectionAvailable),
+ Sinks.EmitFailureHandler.FAIL_FAST
+ )
}
override fun connectionAvailable(): Boolean {
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/web/ConfigController.kt b/src/main/kotlin/dev/dnpm/etl/processor/web/ConfigController.kt
index 44ea400..eb9d541 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/web/ConfigController.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/web/ConfigController.kt
@@ -19,7 +19,10 @@
package dev.dnpm.etl.processor.web
+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.OutputConnectionCheckService
import dev.dnpm.etl.processor.output.MtbFileSender
import dev.dnpm.etl.processor.pseudonym.Generator
import dev.dnpm.etl.processor.security.Role
@@ -40,22 +43,29 @@ import reactor.core.publisher.Sinks
@Controller
@RequestMapping(path = ["configs"])
class ConfigController(
- @Qualifier("configsUpdateProducer")
- private val configsUpdateProducer: Sinks.Many<Boolean>,
+ @Qualifier("connectionCheckUpdateProducer")
+ private val connectionCheckUpdateProducer: Sinks.Many<ConnectionCheckResult>,
private val transformationService: TransformationService,
private val pseudonymGenerator: Generator,
private val mtbFileSender: MtbFileSender,
- private val connectionCheckService: ConnectionCheckService,
+ private val connectionCheckServices: List<ConnectionCheckService>,
private val tokenService: TokenService?,
private val userRoleService: UserRoleService?
) {
@GetMapping
fun index(model: Model): String {
+ val outputConnectionAvailable =
+ connectionCheckServices.filterIsInstance<OutputConnectionCheckService>().first().connectionAvailable()
+
+ val gPasConnectionAvailable =
+ connectionCheckServices.filterIsInstance<GPasConnectionCheckService>().firstOrNull()?.connectionAvailable()
+
model.addAttribute("pseudonymGenerator", pseudonymGenerator.javaClass.simpleName)
model.addAttribute("mtbFileSender", mtbFileSender.javaClass.simpleName)
model.addAttribute("mtbFileEndpoint", mtbFileSender.endpoint())
- model.addAttribute("connectionAvailable", connectionCheckService.connectionAvailable())
+ model.addAttribute("outputConnectionAvailable", outputConnectionAvailable)
+ model.addAttribute("gPasConnectionAvailable", gPasConnectionAvailable)
model.addAttribute("tokensEnabled", tokenService != null)
if (tokenService != null) {
model.addAttribute("tokens", tokenService.findAll())
@@ -73,11 +83,14 @@ class ConfigController(
return "configs"
}
- @GetMapping(params = ["connectionAvailable"])
- fun connectionAvailable(model: Model): String {
+ @GetMapping(params = ["outputConnectionAvailable"])
+ fun outputConnectionAvailable(model: Model): String {
+ val outputConnectionAvailable =
+ connectionCheckServices.filterIsInstance<OutputConnectionCheckService>().first().connectionAvailable()
+
model.addAttribute("mtbFileSender", mtbFileSender.javaClass.simpleName)
model.addAttribute("mtbFileEndpoint", mtbFileSender.endpoint())
- model.addAttribute("connectionAvailable", connectionCheckService.connectionAvailable())
+ model.addAttribute("outputConnectionAvailable", outputConnectionAvailable)
if (tokenService != null) {
model.addAttribute("tokensEnabled", true)
model.addAttribute("tokens", tokenService.findAll())
@@ -85,7 +98,25 @@ class ConfigController(
model.addAttribute("tokens", listOf<Token>())
}
- return "configs/connectionAvailable"
+ return "configs/outputConnectionAvailable"
+ }
+
+ @GetMapping(params = ["gPasConnectionAvailable"])
+ fun gPasConnectionAvailable(model: Model): String {
+ val gPasConnectionAvailable =
+ connectionCheckServices.filterIsInstance<GPasConnectionCheckService>().firstOrNull()?.connectionAvailable()
+
+ model.addAttribute("mtbFileSender", mtbFileSender.javaClass.simpleName)
+ model.addAttribute("mtbFileEndpoint", mtbFileSender.endpoint())
+ model.addAttribute("gPasConnectionAvailable", gPasConnectionAvailable)
+ if (tokenService != null) {
+ model.addAttribute("tokensEnabled", true)
+ model.addAttribute("tokens", tokenService.findAll())
+ } else {
+ model.addAttribute("tokens", listOf<Token>())
+ }
+
+ return "configs/gPasConnectionAvailable"
}
@PostMapping(path = ["tokens"])
@@ -152,9 +183,15 @@ class ConfigController(
@GetMapping(path = ["events"], produces = [MediaType.TEXT_EVENT_STREAM_VALUE])
fun events(): Flux<ServerSentEvent<Any>> {
- return configsUpdateProducer.asFlux().map {
+ return connectionCheckUpdateProducer.asFlux().map {
+ val event = when (it) {
+ is ConnectionCheckResult.KafkaConnectionCheckResult -> "output-connection-check"
+ is ConnectionCheckResult.RestConnectionCheckResult -> "output-connection-check"
+ is ConnectionCheckResult.GPasConnectionCheckResult -> "gpas-connection-check"
+ }
+
ServerSentEvent.builder<Any>()
- .event("connection-available").id("none").data("")
+ .event(event).id("none").data(it)
.build()
}
}
diff --git a/src/main/resources/templates/configs.html b/src/main/resources/templates/configs.html
index 1ac4a26..d94deb6 100644
--- a/src/main/resources/templates/configs.html
+++ b/src/main/resources/templates/configs.html
@@ -45,7 +45,12 @@
</section>
<section hx-ext="sse" th:sse-connect="@{/configs/events}">
- <div th:insert="~{configs/connectionAvailable.html}" th:hx-get="@{/configs?connectionAvailable}" hx-trigger="sse:connection-available">
+ <div th:insert="~{configs/gPasConnectionAvailable.html}" th:hx-get="@{/configs?gPasConnectionAvailable}" hx-trigger="sse:gpas-connection-check">
+ </div>
+ </section>
+
+ <section hx-ext="sse" th:sse-connect="@{/configs/events}">
+ <div th:insert="~{configs/outputConnectionAvailable.html}" th:hx-get="@{/configs?outputConnectionAvailable}" hx-trigger="sse:output-connection-check">
</div>
</section>
</div>
diff --git a/src/main/resources/templates/configs/gPasConnectionAvailable.html b/src/main/resources/templates/configs/gPasConnectionAvailable.html
new file mode 100644
index 0000000..6dccc60
--- /dev/null
+++ b/src/main/resources/templates/configs/gPasConnectionAvailable.html
@@ -0,0 +1,19 @@
+<th:block th:if="${gPasConnectionAvailable == null}">
+ <h2><span>🟦</span> gPAS nicht konfiguriert - Patienten-IDs werden intern anonymisiert</h2>
+</th:block>
+<th:block th:if="${gPasConnectionAvailable != null}">
+ <h2><span th:if="${gPasConnectionAvailable}">✅</span><span th:if="${not(gPasConnectionAvailable)}">⚡</span> Verbindung zu gPAS</h2>
+ <div>
+ Die Verbindung ist aktuell
+ <strong th:if="${gPasConnectionAvailable}" style="color: green">verfügbar.</strong>
+ <strong th:if="${not(gPasConnectionAvailable)}" style="color: red">nicht verfügbar.</strong>
+ </div>
+ <div class="connection-display border">
+ <img th:src="@{/server.png}" alt="ETL-Processor" />
+ <span class="connection" th:classappend="${gPasConnectionAvailable ? 'available' : ''}"></span>
+ <img th:src="@{/server.png}" alt="gPAS" />
+ <span>ETL-Processor</span>
+ <span></span>
+ <span>gPAS</span>
+ </div>
+</th:block> \ No newline at end of file
diff --git a/src/main/resources/templates/configs/connectionAvailable.html b/src/main/resources/templates/configs/outputConnectionAvailable.html
index 6d52d70..2b18b75 100644
--- a/src/main/resources/templates/configs/connectionAvailable.html
+++ b/src/main/resources/templates/configs/outputConnectionAvailable.html
@@ -1,12 +1,12 @@
-<h2><span th:if="${connectionAvailable}">✅</span><span th:if="${not(connectionAvailable)}">⚡</span> Verbindung zum bwHC-Backend</h2>
+<h2><span th:if="${outputConnectionAvailable}">✅</span><span th:if="${not(outputConnectionAvailable)}">⚡</span> MTB-File Verbindung</h2>
<div>
Verbindung über <code>[[ ${mtbFileSender} ]]</code>. Die Verbindung ist aktuell
- <strong th:if="${connectionAvailable}" style="color: green">verfügbar.</strong>
- <strong th:if="${not(connectionAvailable)}" style="color: red">nicht verfügbar.</strong>
+ <strong th:if="${outputConnectionAvailable}" style="color: green">verfügbar.</strong>
+ <strong th:if="${not(outputConnectionAvailable)}" style="color: red">nicht verfügbar.</strong>
</div>
<div class="connection-display border">
<img th:src="@{/server.png}" alt="ETL-Processor" />
- <span class="connection" th:classappend="${connectionAvailable ? 'available' : ''}"></span>
+ <span class="connection" th:classappend="${outputConnectionAvailable ? 'available' : ''}"></span>
<img th:if="${mtbFileSender.startsWith('Rest')}" th:src="@{/server.png}" alt="bwHC-Backend" />
<img th:if="${mtbFileSender.startsWith('Kafka')}" th:src="@{/kafka.png}" alt="Kafka-Broker" />
<span>ETL-Processor</span>