Zum Hauptinhalt springen

Tutorial: Empfangen und antworten

Typ A/B · Verwaltung   Dauer: ca. 20 Minuten

Was Sie hier bauen: Ein Programm, das als Verwaltungssystem den Antrag aus Tutorial 1 abholt, den Prüfbericht ausgibt, den Antrag annimmt und einen Bescheid als Antwort in denselben Vorgang sendet. Am Ende sehen Sie im Ereignisprotokoll den signierten Zustand ACCEPTED.

Lernziel, nicht Produktivcode

Dieses Tutorial optimiert auf Verstehen. Was für den Betrieb fehlt (Vault statt Datei, Callbacks statt Polling, Locking bei mehreren Instanzen), steht in den Rezepten Anträge abholen und prüfen und Callbacks prüfen.


Voraussetzungen​

  • Ein Zustellpunkt vom Typ A („Verwaltung“) im Self-Service-Portal (TEST) und ein API-Client mit den Scopes zum Abholen und Antworten.
  • Ein Antrag, der an diesen Zustellpunkt gesendet wurde — z. B. aus Tutorial 1, dessen submissionId und caseId Sie notiert haben.
  • Das Projekt aus Tutorial 1 (oder ein neues nach demselben Muster).

Schritt 1: Schlüssel erzeugen und hinterlegen​

Ein Empfänger braucht zwei private Schlüssel: einen zum Entschlüsseln der Anträge und einen zum Signieren seiner Events (Annahme, Ablehnung, Antwort). Die öffentlichen Hälften laden Sie im Portal am Zustellpunkt hoch. Für TEST erzeugen Sie die Paare lokal:

JWKPair enc = EncryptionKeyPairGenerator.generate("tutorial-enc");
JWKPair sig = EncryptionKeyPairGenerator.generate("tutorial-sig");

Files.writeString(Path.of("decrypt.jwk"), enc.privateKey().toJSONString());
Files.writeString(Path.of("sign.jwk"), sig.privateKey().toJSONString());
System.out.println(enc.publicKey().toJSONString()); // → Portal: Verschlüsselungsschlüssel
System.out.println(sig.publicKey().toJSONString()); // → Portal: Signaturschlüssel

Alternativ erledigt das die Kommandozeile in einem Schritt: fit-connect keygen --with-config schreibt beide Paare und eine passende config.yml (siehe Kommandozeile).

Regel 4 des Rollenmodells: Schlüssel bestimmen, was Sie öffnen können. Zum Senden brauchten Sie in Tutorial 1 keinen — zum Empfangen brauchen Sie beide. Mehr dazu unter Schlüssel und Rollover.


Schritt 2: Als Organisation auftreten​

FitConnectSdk sdk = FitConnectSdk.fromConfigYaml(Path.of("config.yml"));

DestinationKeys keys = new DestinationKeys(
JWK.parse(Files.readString(Path.of("decrypt.jwk"))),
JWK.parse(Files.readString(Path.of("sign.jwk"))));

Organisation organisation = sdk.organisation(MY_DESTINATION_ID, keys); // Typ A

Schritt 3: Antrag abholen und Prüfbericht lesen​

ReceivedSubmission received = organisation.receive(SUBMISSION_ID); // aus Tutorial 1

System.out.println("Fachdaten: " + received.getDataAsString());
System.out.println("Bericht: " + (received.acceptable() ? "keine Fehler" : "Fehler"));
System.out.println(received.report().describe());

Der Antrag kommt immer entschlüsselt zurück, zusammen mit einem Prüfbericht. Ist er in Ordnung, ist der Bericht leer; sonst steht dort pro Fund eine Zeile mit Lösungsvorschlag. Warum das SDK hier nicht selbst ablehnt, erklärt Der Prüfbericht.


Schritt 4: Annehmen​

if (!received.acceptable()) {
organisation.reject(received, received.report().asProblems());
return;
}
organisation.accept(received); // signiertes Event
System.out.println("✓ Antrag angenommen");
Nach dem Annehmen ist der Antrag gelöscht

Mit accept wechselt die Submission in den Zustand deleted und wird vom Zustelldienst entfernt. Speichern Sie Fachdaten und Anhänge vorher in Ihrem Fachverfahren.


Schritt 5: Antworten​

Hat der Onlinedienst einen FIT-Connect-Rückkanal mitgegeben (in Tutorial 1 nicht — dazu gleich mehr), senden Sie den Bescheid als Antwort in denselben Vorgang:

SentReply reply = organisation.send(OutgoingReply.answering(received)
.setData(SubmissionData.json(
"{\"entscheidung\": \"bewilligt\"}",
URI.create("https://schema.fitko.de/fit-connect/fitconnect_demo_0.1.schema.json")))
.build());

System.out.println("✓ Antwort gesendet: " + reply.id());

answering(received) / ForSubmission(received) übernimmt caseId und Rückkanalschlüssel aus dem Antrag — Sie können nicht in den falschen Vorgang antworten. Fehlt der Rückkanal, endet der Aufruf mit FitConnectReplyException: Der Antrag aus Tutorial 1 hat keinen. Wie der Onlinedienst einen mitgibt und die Antwort später liest, ist der Inhalt von Antworten senden und lesen.


Schritt 6: Ausführen und prüfen​

mvn compile exec:java -Dexec.mainClass="de.example.App"

Erwartete Ausgabe:

Fachdaten: {"message": "Hallo aus dem Tutorial!"}
Bericht: keine Fehler
✓ Antrag angenommen

Im Self-Service-Portal steht der Antrag jetzt auf ACCEPTED — signiert mit Ihrem Signaturschlüssel. Ein Onlinedienst sieht denselben Zustand mit Status verfolgen.


Was Sie gelernt haben​

  • Ein Empfänger braucht zwei Schlüssel; das SDK bekommt sie beim Erzeugen der Rolle (Java) bzw. aus der Konfiguration (.NET) — nie neben den Credentials in einer eingecheckten Datei.
  • receive / FetchSubmission liefert den Antrag immer mit Prüfbericht; annehmen oder ablehnen ist Ihr expliziter Aufruf.
  • Eine Antwort adressiert den Vorgang, nicht den Zustellpunkt — und braucht den Rückkanal, den der Onlinedienst mitgeschickt hat.

Was als Nächstes?​