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)

pom.xml
    <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:

Erzeugen einer ZetaClientSDK-Instanz
  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

  1. einen Account anlegen
  2. eine Abfrage nach einem Versichertenaccount ausführen

Fachliche DiPag-APIs über ZETA aufrufen
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



  • No labels