Das ZETA Client SDK (Kotlin Multiplatform) übernimmt die gesamte ZETA-Client-Logik. Rechnungserstellende Systeme konfigurieren es einmal und rufen dann den Fachdienst über den ZetaHttpClient des SDK auf. Dieses Kapitel gilt für Rechnungsersteller und Kostenträger.
Ein schon für andere TI-2.0-Dienste wie PoPP und VSDM2 konfigurierter ZETA-Client kann für den Dienst Digitale Patientenrechnung nachgenutzt werden.
Die Beispiele hier sind in Java erstellt. Für C#/C++ siehe die READMEs in https://github.com/gematik/zeta-sdk/tree/main/zeta-client-cpp und https://github.com/gematik/zeta-sdk/tree/main/zeta-client-csharp
Einbinden der Zeta SDK Library (hier gezeigt mit Maven)
<properties>
<maven.compiler.release>17</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<zeta-sdk.version>1.0.1</zeta-sdk.version>
<main.class>DipagClient</main.class>
</properties>
<dependencies>
<dependency>
<groupId>de.gematik.zeta</groupId>
<artifactId>zeta-sdk-jvm</artifactId>
<version>${zeta-sdk.version}</version>
</dependency>
</dependencies>
Die Hier gezeigte Version ZETA 1.0.1. ist derzeit kompatibel mit dem noch Entwicklung befindlichen Fachdienst. Ein Update auf ZETA 1.3.x ist in Arbeit.
Zeta Client erzeugen
Das Zeta-Client-SDK bietet mit dem ZetaSdkClient - Objekt und einem zugehörigen Http-Client alle notwendigen Schnittstellen zur sicheren Interaktion mit dem Fachdienst Digitale Patientenrechnung.
Zunächst wird eine Instanz des ZetaSdkClient erzeugt:
private final static List<String> scopes = List.of("dipag", "practitionerAccount.crud");
private final static String smbKeystore = ./smcb-4711.p12;
...
private static ZetaSdkClient buildClient(final List<String> scopes, final String smbKeystore) {
String diPagServer = "https://dev2.digitale-patientenrechnung.de/"; //RU-DEV Interim mit altem ZETA Stand 1.0.1
String STORAGE_KEY = "KqOHTbtH1711eFd/PUMFSISxsJA3U1n4eweFljdtoTA="; //DEMO
final StorageConfig storageConfig = new StorageConfig.Default(STORAGE_KEY, null);
return
ZetaSdk.INSTANCE.build(
diPagServer,
new BuildConfig(
"DiPag-Demo-Client",
"0.1.0",
"dipag-client",
storageConfig,
new TpmConfig() { // kein TPM
},
new AuthConfig(
scopes,
30,
false,
new SmbTokenProvider(new SmbTokenProvider.Credentials(
smbKeystore,
"alias", // alias in keystore
"password", // keystore passwort
"")),
AttestationConfig.software(),
""),
new PlatformProductId.WindowsProductId("windows", "storeId", ""),
new ZetaHttpClientBuilder().logging(LogLevel.ALL),
null,
null,
null));
}
}
Für einen Test in der Testumgebung sind hier relevant:
- Der SMB-Keystore: keystore mit einem SMC-B - Zertifikat, welches die Identität repräsentiert, mit der zugegriffen werden soll. Dies "simuliert" den Einsatz einer echten SMC-B-Karte. Testzertifikate für Hersteller können bei der Gematik bezogen werden.
- Die Scopes, für die der so erzeugte Zeta-Client entsprechende Access Tokens verwalten soll.
Die einzelnen Http-Endpunkte des Fachdienstes benötigen jeweils unterschiedliche Scopes, siehe Implementierungsleitfaden Rechnungsersteller und Implementierungsleitfaden Kostenträger. Daher muss entweder
- Ein einzelner ZetaSDKClient erzeugt werden, der mit allen potentiell benötigten Scopes gebaut wurde oder
- Für jeden Use Case mit unterschiedlichen benötigten Scopes eine eigene ZetaSDKClient - Instanz erzeugt werden. (Das hier angehängte Beispiel wählt diese Lösung)
Mittels HTTPClient des ZetaSDKClients die fachlichen APIs aufrufen
So kann mit Hilfe des ZetaSDKClients z.B. ein rechnungserstellendes System
- einen Account anlegen
- eine Abfrage nach einem Versichertenaccount ausführen
httpClientAccountAPI = sdkClientAccount.httpClient(it -> {return Unit.INSTANCE;});
httpClientFhirAPI = sdkClientFHIR.httpClient(it -> {return Unit.INSTANCE;});
final Map<String, String> headers = Map.of("Accept", "application/json");
// create account
var acccountRequest = HttpClientExtension.postAsync(httpClientAccountAPI, "/api/PractitionerAccount", headers, CREATE_INSTITUTION_BODY);
var responseAccountCreation = acccountRequest.join();
int status = responseAccountCreation.getStatus().getValue();
if(status != 201) { ... Fehler ... }
// search patient
var patientRequest = HttpClientExtension.getAsync(httpClientFhirAPI, "/fhir/Patient?identifier=V202606242&birthdate=1965-02-01", headers);
var responsePatient = patientRequest.join();
var responseBodyPatient = HttpClientExtension.bodyAsText(responsePatient).join();
Bei dem hier gezeigte Ablauf
- SDK erzeugen
- HTTP - Request senden
werden die Schritte "Registrierung" und "Autorisierung" automatisch im Hintergrund aufgerufen, sofern sie noch nicht ausgeführt wurden. Das SDK bietet allen Systemen auch die Möglichkeit jeden Schritt separat anzusteuern:
interface ZetaSdkClient {
suspend fun discover(): Result<Unit>
suspend fun register(): Result<Unit>
suspend fun authenticate(): Result<Unit>
fun httpClient(builder: ZetaHttpClientBuilder.() -> Unit = {}): ZetaHttpClient
suspend fun <R> ws(
targetUrl: String,
builder: ZetaHttpClientBuilder.() -> Unit = {},
customHeaders: Map<String, String>? = null,
block: suspend DefaultClientWebSocketSession.() -> R,
)
suspend fun status(): Result<SdkStatus>
suspend fun logout(): Result<Unit>
suspend fun close(): Result<Unit>
suspend fun changeEmail(newEmail: String): Result<ChangeEmailResponse>
}
Weiterführende Informationen zum ZETA Client SDK: https://github.com/gematik/zeta-sdk