diff --git a/project-repo/de/servicehealth/lib-cetp/1.0.0-SNAPSHOT/_remote.repositories b/project-repo/de/servicehealth/lib-cetp/1.0.0-SNAPSHOT/_remote.repositories
index 723a6a97..262fc994 100644
--- a/project-repo/de/servicehealth/lib-cetp/1.0.0-SNAPSHOT/_remote.repositories
+++ b/project-repo/de/servicehealth/lib-cetp/1.0.0-SNAPSHOT/_remote.repositories
@@ -1,5 +1,5 @@
#NOTE: This is a Maven Resolver internal implementation file, its format can be changed without prior notice.
-#Wed Oct 16 22:40:04 AMT 2024
+#Thu Oct 17 14:12:52 AMT 2024
lib-cetp-1.0.0-SNAPSHOT-sources.jar>=
lib-cetp-1.0.0-SNAPSHOT.jar>=
lib-cetp-1.0.0-SNAPSHOT.pom>=
diff --git a/project-repo/de/servicehealth/lib-cetp/1.0.0-SNAPSHOT/lib-cetp-1.0.0-SNAPSHOT-sources.jar b/project-repo/de/servicehealth/lib-cetp/1.0.0-SNAPSHOT/lib-cetp-1.0.0-SNAPSHOT-sources.jar
index d008e846..40f564ac 100644
Binary files a/project-repo/de/servicehealth/lib-cetp/1.0.0-SNAPSHOT/lib-cetp-1.0.0-SNAPSHOT-sources.jar and b/project-repo/de/servicehealth/lib-cetp/1.0.0-SNAPSHOT/lib-cetp-1.0.0-SNAPSHOT-sources.jar differ
diff --git a/project-repo/de/servicehealth/lib-cetp/1.0.0-SNAPSHOT/lib-cetp-1.0.0-SNAPSHOT.jar b/project-repo/de/servicehealth/lib-cetp/1.0.0-SNAPSHOT/lib-cetp-1.0.0-SNAPSHOT.jar
index 07975714..afe4a410 100644
Binary files a/project-repo/de/servicehealth/lib-cetp/1.0.0-SNAPSHOT/lib-cetp-1.0.0-SNAPSHOT.jar and b/project-repo/de/servicehealth/lib-cetp/1.0.0-SNAPSHOT/lib-cetp-1.0.0-SNAPSHOT.jar differ
diff --git a/project-repo/de/servicehealth/lib-cetp/1.0.0-SNAPSHOT/maven-metadata-local.xml b/project-repo/de/servicehealth/lib-cetp/1.0.0-SNAPSHOT/maven-metadata-local.xml
index fae84606..6fff50d9 100644
--- a/project-repo/de/servicehealth/lib-cetp/1.0.0-SNAPSHOT/maven-metadata-local.xml
+++ b/project-repo/de/servicehealth/lib-cetp/1.0.0-SNAPSHOT/maven-metadata-local.xml
@@ -3,7 +3,7 @@
de.servicehealth
lib-cetp
- 20241016183958
+ 20241017101246
true
@@ -11,18 +11,18 @@
pom
1.0.0-SNAPSHOT
- 20241016183958
+ 20241017101246
jar
1.0.0-SNAPSHOT
- 20241016183958
+ 20241017101246
sources
jar
1.0.0-SNAPSHOT
- 20241016183958
+ 20241017101246
diff --git a/project-repo/de/servicehealth/lib-cetp/maven-metadata-local.xml b/project-repo/de/servicehealth/lib-cetp/maven-metadata-local.xml
index 61eaba45..5c33e583 100644
--- a/project-repo/de/servicehealth/lib-cetp/maven-metadata-local.xml
+++ b/project-repo/de/servicehealth/lib-cetp/maven-metadata-local.xml
@@ -6,6 +6,6 @@
1.0.0-SNAPSHOT
- 20241016183958
+ 20241017101246
diff --git a/src/main/java/health/ere/ps/service/cetp/CETPServerHandler.java b/src/main/java/health/ere/ps/service/cetp/CETPServerHandler.java
index 9a10ada5..780db06c 100644
--- a/src/main/java/health/ere/ps/service/cetp/CETPServerHandler.java
+++ b/src/main/java/health/ere/ps/service/cetp/CETPServerHandler.java
@@ -2,22 +2,21 @@
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.parser.IParser;
-import de.gematik.ws.conn.eventservice.v7.Event;
+import de.health.service.cetp.AbstractCETPEventHandler;
import de.health.service.cetp.cardlink.CardlinkWebsocketClient;
import de.servicehealth.config.api.IUserConfigurations;
import health.ere.ps.config.RuntimeConfig;
import health.ere.ps.service.cetp.tracker.TrackerService;
import health.ere.ps.service.gematik.PharmacyService;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelInboundHandlerAdapter;
import jakarta.json.Json;
import jakarta.json.JsonArrayBuilder;
import org.apache.commons.lang3.tuple.Pair;
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.Bundle.BundleEntryComponent;
+import org.hl7.fhir.r4.model.Identifier;
+import org.hl7.fhir.r4.model.Task;
import org.jboss.logging.MDC;
-import java.net.InetSocketAddress;
import java.util.Map;
import java.util.UUID;
import java.util.logging.Level;
@@ -26,13 +25,12 @@
import static de.health.service.cetp.utils.Utils.printException;
-public class CETPServerHandler extends ChannelInboundHandlerAdapter {
+public class CETPServerHandler extends AbstractCETPEventHandler {
private static final Logger log = Logger.getLogger(CETPServerHandler.class.getName());
TrackerService trackerService;
PharmacyService pharmacyService;
- CardlinkWebsocketClient cardlinkWebsocketClient;
IParser parser = FhirContext.forR4().newXmlParser();
@@ -41,130 +39,85 @@ public CETPServerHandler(
PharmacyService pharmacyService,
CardlinkWebsocketClient cardlinkWebsocketClient
) {
+ super(cardlinkWebsocketClient);
this.trackerService = trackerService;
this.pharmacyService = pharmacyService;
- this.cardlinkWebsocketClient = cardlinkWebsocketClient;
}
@Override
- public void handlerAdded(ChannelHandlerContext ctx) {
+ protected String getTopicName() {
+ return "CARD/INSERTED";
}
@Override
- public void handlerRemoved(ChannelHandlerContext ctx) {
- }
-
- @Override
- public void channelRead(ChannelHandlerContext ctx, Object msg) {
- try {
- String correlationId = UUID.randomUUID().toString();
- MDC.put("requestCorrelationId", correlationId); // Keep MDC name in snyc with virtual-nfc-cardlink
- cardlinkWebsocketClient.connect();
-
- @SuppressWarnings("unchecked")
- Pair input = (Pair) msg;
- Event event = input.getKey();
-
- if (event.getTopic().equals("CARD/INSERTED")) {
- final Map eventMap = event.getMessage().getParameter().stream()
- .collect(Collectors.toMap(Event.Message.Parameter::getKey, Event.Message.Parameter::getValue));
-
- // Keep MDC names in sync with virtual-nfc-cardlink
- MDC.put("iccsn", eventMap.getOrDefault("ICCSN", "NoICCSNProvided"));
- MDC.put("ctid", eventMap.getOrDefault("CtID", "NoCtIDProvided"));
- MDC.put("slot", eventMap.getOrDefault("SlotID", "NoSlotIDProvided"));
- log.fine("CARD/INSERTED event received with the following payload: %s".formatted(eventMap));
-
- if ("EGK".equalsIgnoreCase(eventMap.get("CardType")) && eventMap.containsKey("CardHandle") && eventMap.containsKey("SlotID") && eventMap.containsKey("CtID")) {
- String cardHandle = eventMap.get("CardHandle");
- Integer slotId = Integer.parseInt(eventMap.get("SlotID"));
- String ctId = eventMap.get("CtID");
- String iccsn = eventMap.get("ICCSN");
- Long endTime = System.currentTimeMillis();
-
-
- String paramsStr = event.getMessage().getParameter().stream()
- .filter(p -> !p.getKey().equals("CardHolderName"))
- .map(p -> String.format("key=%s value=%s", p.getKey(), p.getValue())).collect(Collectors.joining(", "));
-
- log.fine(String.format("[%s] Card inserted: params: %s", correlationId, paramsStr));
- try {
- IUserConfigurations uc = input.getValue();
- RuntimeConfig runtimeConfig = new RuntimeConfig(uc);
- Pair pair = pharmacyService.getEPrescriptionsForCardHandle(
- correlationId, cardHandle, null, runtimeConfig
- );
- Bundle bundle = pair.getKey();
- String eventId = pair.getValue();
- String xml = parser.encodeToString(bundle);
- cardlinkWebsocketClient.sendJson(correlationId, iccsn, "eRezeptTokensFromAVS", Map.of("slotId", slotId, "ctId", ctId, "tokens", xml));
-
- JsonArrayBuilder bundles = prepareBundles(correlationId, bundle, runtimeConfig);
- cardlinkWebsocketClient.sendJson(correlationId, iccsn, "eRezeptBundlesFromAVS", Map.of("slotId", slotId, "ctId", ctId, "bundles", bundles));
-
- cardlinkWebsocketClient.sendJson(correlationId, iccsn, "vsdmSensorData", Map.of("slotId", slotId, "ctId", ctId, "endTime", endTime, "eventId", eventId));
-
- trackerService.submit(ctId, uc.getMandantId(), uc.getWorkplaceId(), uc.getClientSystemId());
- } catch (Exception e ) {
- log.log(Level.WARNING, String.format("[%s] Could not get prescription for Bundle", correlationId), e);
-
- if (e instanceof de.gematik.ws.conn.vsds.vsdservice.v5.FaultMessage faultMessage) {
- String code = faultMessage.getFaultInfo().getTrace().get(0).getCode().toString();
- cardlinkWebsocketClient.sendJson(correlationId, iccsn, "vsdmSensorData", Map.of("slotId", slotId, "ctId", ctId, "endTime", endTime, "err", code));
- }
- if (e instanceof de.gematik.ws.conn.eventservice.wsdl.v7.FaultMessage faultMessage) {
- String code = faultMessage.getFaultInfo().getTrace().get(0).getCode().toString();
- cardlinkWebsocketClient.sendJson(correlationId, iccsn, "vsdmSensorData", Map.of("slotId", slotId, "ctId", ctId, "endTime", endTime, "err", code));
- }
-
- String error = printException(e);
- cardlinkWebsocketClient.sendJson(
- correlationId,
- iccsn,
- "receiveTasklistError",
- Map.of("slotId", slotId, "cardSessionId", "null", "status", 500, "tistatus", "500", "errormessage", error)
- );
- }
- } else {
- String msgFormat = "Ignored \"CARD/INSERTED\" event=%s: values=%s";
- log.log(Level.INFO, String.format(msgFormat, event.getMessage(), eventMap));
+ protected void processEvent(IUserConfigurations uc, Map paramsMap) {
+ // Keep MDC names in sync with virtual-nfc-cardlink
+ String correlationId = UUID.randomUUID().toString();
+ MDC.put("requestCorrelationId", correlationId);
+ MDC.put("iccsn", paramsMap.getOrDefault("ICCSN", "NoICCSNProvided"));
+ MDC.put("ctid", paramsMap.getOrDefault("CtID", "NoCtIDProvided"));
+ MDC.put("slot", paramsMap.getOrDefault("SlotID", "NoSlotIDProvided"));
+ log.fine("CARD/INSERTED event received with the following payload: %s".formatted(paramsMap));
+
+ if ("EGK".equalsIgnoreCase(paramsMap.get("CardType")) && paramsMap.containsKey("CardHandle") && paramsMap.containsKey("SlotID") && paramsMap.containsKey("CtID")) {
+ String cardHandle = paramsMap.get("CardHandle");
+ Integer slotId = Integer.parseInt(paramsMap.get("SlotID"));
+ String ctId = paramsMap.get("CtID");
+ String iccsn = paramsMap.get("ICCSN");
+ Long endTime = System.currentTimeMillis();
+
+
+ String paramsStr = paramsMap.entrySet().stream()
+ .filter(p -> !p.getKey().equals("CardHolderName"))
+ .map(p -> String.format("key=%s value=%s", p.getKey(), p.getValue())).collect(Collectors.joining(", "));
+
+ log.fine(String.format("[%s] Card inserted: params: %s", correlationId, paramsStr));
+ try {
+ RuntimeConfig runtimeConfig = new RuntimeConfig(uc);
+ Pair pair = pharmacyService.getEPrescriptionsForCardHandle(
+ correlationId, cardHandle, null, runtimeConfig
+ );
+ Bundle bundle = pair.getKey();
+ String eventId = pair.getValue();
+ String xml = parser.encodeToString(bundle);
+ cardlinkWebsocketClient.sendJson(correlationId, iccsn, "eRezeptTokensFromAVS", Map.of("slotId", slotId, "ctId", ctId, "tokens", xml));
+
+ JsonArrayBuilder bundles = prepareBundles(correlationId, bundle, runtimeConfig);
+ cardlinkWebsocketClient.sendJson(correlationId, iccsn, "eRezeptBundlesFromAVS", Map.of("slotId", slotId, "ctId", ctId, "bundles", bundles));
+
+ cardlinkWebsocketClient.sendJson(correlationId, iccsn, "vsdmSensorData", Map.of("slotId", slotId, "ctId", ctId, "endTime", endTime, "eventId", eventId));
+
+ trackerService.submit(ctId, uc.getMandantId(), uc.getWorkplaceId(), uc.getClientSystemId());
+ } catch (Exception e ) {
+ log.log(Level.WARNING, String.format("[%s] Could not get prescription for Bundle", correlationId), e);
+
+ if (e instanceof de.gematik.ws.conn.vsds.vsdservice.v5.FaultMessage faultMessage) {
+ String code = faultMessage.getFaultInfo().getTrace().get(0).getCode().toString();
+ cardlinkWebsocketClient.sendJson(correlationId, iccsn, "vsdmSensorData", Map.of("slotId", slotId, "ctId", ctId, "endTime", endTime, "err", code));
+ }
+ if (e instanceof de.gematik.ws.conn.eventservice.wsdl.v7.FaultMessage faultMessage) {
+ String code = faultMessage.getFaultInfo().getTrace().get(0).getCode().toString();
+ cardlinkWebsocketClient.sendJson(correlationId, iccsn, "vsdmSensorData", Map.of("slotId", slotId, "ctId", ctId, "endTime", endTime, "err", code));
}
- }
-
- } finally {
- cardlinkWebsocketClient.close();
- MDC.clear();
- }
- }
-
- @Override
- public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
- if (log.isLoggable(Level.FINE)) {
- String port = "unknown";
- if (ctx.channel().localAddress() instanceof InetSocketAddress inetSocketAddress) {
- port = String.valueOf(inetSocketAddress.getPort());
- }
- log.fine(String.format("New CETP connection established (on port %s)", port));
- }
- super.channelRegistered(ctx);
- }
- @Override
- public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
- if (log.isLoggable(Level.FINE)) {
- String port = "unknown";
- if (ctx.channel().localAddress() instanceof InetSocketAddress inetSocketAddress) {
- port = String.valueOf(inetSocketAddress.getPort());
+ String error = printException(e);
+ cardlinkWebsocketClient.sendJson(
+ correlationId,
+ iccsn,
+ "receiveTasklistError",
+ Map.of("slotId", slotId, "cardSessionId", "null", "status", 500, "tistatus", "500", "errormessage", error)
+ );
}
- log.fine(String.format("CETP connection was closed (on port %s)", port));
+ } else {
+ String msgFormat = "Ignored \"CARD/INSERTED\" values=%s";
+ log.log(Level.INFO, String.format(msgFormat, paramsMap));
}
- super.channelUnregistered(ctx);
}
private JsonArrayBuilder prepareBundles(String correlationId, Bundle bundle, RuntimeConfig runtimeConfig) {
JsonArrayBuilder bundles = Json.createArrayBuilder();
for (BundleEntryComponent entry : bundle.getEntry()) {
- if (entry.getResource() instanceof org.hl7.fhir.r4.model.Task) {
+ if (entry.getResource() instanceof Task task) {
/*
*
*
@@ -178,9 +131,8 @@ private JsonArrayBuilder prepareBundles(String correlationId, Bundle bundle, Run
*
*/
- org.hl7.fhir.r4.model.Task task = (org.hl7.fhir.r4.model.Task) entry.getResource();
- String taskId = task.getIdentifier().stream().filter(t -> "https://gematik.de/fhir/erp/NamingSystem/GEM_ERP_NS_PrescriptionId".equals(t.getSystem())).map(t -> t.getValue()).findAny().orElse(null);
- String accessCode = task.getIdentifier().stream().filter(t -> "https://gematik.de/fhir/erp/NamingSystem/GEM_ERP_NS_AccessCode".equals(t.getSystem())).map(t -> t.getValue()).findAny().orElse(null);
+ String taskId = task.getIdentifier().stream().filter(t -> "https://gematik.de/fhir/erp/NamingSystem/GEM_ERP_NS_PrescriptionId".equals(t.getSystem())).map(Identifier::getValue).findAny().orElse(null);
+ String accessCode = task.getIdentifier().stream().filter(t -> "https://gematik.de/fhir/erp/NamingSystem/GEM_ERP_NS_AccessCode".equals(t.getSystem())).map(Identifier::getValue).findAny().orElse(null);
log.fine("TaskId: " + taskId + " AccessCode: " + accessCode);
String token = "/Task/" + taskId + "/$accept?ac=" + accessCode;
try {
@@ -193,10 +145,4 @@ private JsonArrayBuilder prepareBundles(String correlationId, Bundle bundle, Run
}
return bundles;
}
-
- @Override
- public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
- log.log(Level.SEVERE, "Caught an exception handling CETP input", cause);
- ctx.close();
- }
}
diff --git a/src/main/java/health/ere/ps/service/cetp/CETPServerHandlerFactory.java b/src/main/java/health/ere/ps/service/cetp/CETPServerHandlerFactory.java
index 46026270..89cd5e4b 100644
--- a/src/main/java/health/ere/ps/service/cetp/CETPServerHandlerFactory.java
+++ b/src/main/java/health/ere/ps/service/cetp/CETPServerHandlerFactory.java
@@ -43,7 +43,7 @@ public CETPServerHandlerFactory(
}
@Override
- public ChannelInboundHandler build(KonnektorConfig kc) {
+ public ChannelInboundHandler[] build(KonnektorConfig kc) {
CardlinkWebsocketClient cardlinkWebsocketClient = new CardlinkWebsocketClient(
kc.getCardlinkEndpoint(),
new EreJwtConfigurator(
@@ -56,6 +56,8 @@ public ChannelInboundHandler build(KonnektorConfig kc) {
kc.getCardlinkEndpoint(),
cardlinkWebsocketClient.connected()
);
- return new CETPServerHandler(trackerService, pharmacyService, cardlinkWebsocketClient);
+ return new CETPServerHandler[] {
+ new CETPServerHandler(trackerService, pharmacyService, cardlinkWebsocketClient)
+ };
}
}
diff --git a/src/main/java/health/ere/ps/service/cetp/codec/CETPDecoder.java b/src/main/java/health/ere/ps/service/cetp/codec/CETPDecoder.java
index d0d296f6..e78fa941 100644
--- a/src/main/java/health/ere/ps/service/cetp/codec/CETPDecoder.java
+++ b/src/main/java/health/ere/ps/service/cetp/codec/CETPDecoder.java
@@ -1,13 +1,14 @@
package health.ere.ps.service.cetp.codec;
import de.gematik.ws.conn.eventservice.v7.Event;
+import de.health.service.cetp.domain.eventservice.event.DecodeResult;
+import de.health.service.cetp.domain.eventservice.event.mapper.CetpEventMapper;
import de.servicehealth.config.api.IUserConfigurations;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBException;
-import org.apache.commons.lang3.tuple.Pair;
import java.io.StringReader;
import java.nio.charset.StandardCharsets;
@@ -20,7 +21,6 @@ public class CETPDecoder extends ByteToMessageDecoder {
private static final Logger log = Logger.getLogger(CETPDecoder.class.getName());
static JAXBContext jaxbContext;
-
static {
try {
jaxbContext = JAXBContext.newInstance(Event.class);
@@ -28,37 +28,35 @@ public class CETPDecoder extends ByteToMessageDecoder {
log.log(Level.SEVERE, "Failed to create JAXB context", e);
}
}
- IUserConfigurations userConfigurations;
- public CETPDecoder() {
+ IUserConfigurations configurations;
+ CetpEventMapper eventMapper;
+ public CETPDecoder() {
}
- public CETPDecoder(IUserConfigurations userConfigurations) {
- this.userConfigurations = userConfigurations;
+ public CETPDecoder(IUserConfigurations configurations, CetpEventMapper eventMapper) {
+ this.configurations = configurations;
+ this.eventMapper = eventMapper;
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List