Java-SDK
Verwaltungssystem implementieren
Empfangende Systeme (in der Regel: Verwaltungssysteme) erhalten Einreichungen von Antragsteller:innen über FIT-Connect. Das Empfangen von Anträgen ist auf der Seite Abruf von Einreichungen beschrieben.
Das Java-SDK setzt Details wie Validierungen und Entschlüsselung intern um, sodass Sie sich bei der Anbindung auf die Implementierung der Schnittstelle fokussieren können.
Im Folgenden wird gezeigt, wie Sie mit dem Java-SDK eine Submission von einem Zustellpunkt abrufen.
Konfiguration erstellen
Für die Implementierung eines Verwaltungsystems benötigen Sie zunächst eine Konfiguration.
Diese kann über die YAML Datei config.yml
, oder programmatisch über einen Builder der Klasse ApplicationConfig
erstellt werden.
Unter Java-SDK - Überblick ist beschrieben, wie Sie Informationen für ein Verwaltungssystem in diese Datei eintragen.
Java | YAML |
|
Die YAML Konfiguration wird anschließend mit dem
|
Client für Verwaltungssystem erstellen
Im nächsten Schritt wird ein SubscriberClient
benötigt, der mittels der ClientFactory
erzeugt werden kann.
SubscriberClient subscriberClient = ClientFactory.createSubscriberClient(config);
Submission laden
Das Laden von Submissions erfolgt in zwei Schritten.
- Erfragen, ob abholbereite Submissions für einen Zustellpunkt vorliegen.
Dieser Schritt ist nicht erforderlich, wenn das Verwaltungssystem durch einen Callback darüber informiert wird, dass Submissions abholbereit sind. - Abholen einer bestimmten Submission.
Abholbereite Submissions erfragen
Das folgende Beispiel zeigt, wie Sie beim Zustelldienst erfragen, ob für einen Zustellpunkt (eine Destination) Submissions zur Abholung bereitstehen:
SubscriberClient subscriberClient = ClientFactory.createSubscriberClient(config);
int offset = 0;
int limit = 100;
var destinationId = UUID.fromString("d2d43892-9d9c-4630-980a-5af341179b14");
Set<SubmissionForPickup> availableSubmissions = subscriberClient.getAvailableSubmissionsforDestination(destinationId, limit, offset);
Von der Methode getAvailableSubmissionsforDestination
erhalten Sie die IDs der abholbereiten Einreichungen (siehe Beispiel oben).
Mittels Paging werden über die Angabe von limit
und offset
Teilresultate geladen.
Die im Set
enthaltenen SubmissionForPickup
ermöglichen den Zugriff auf destinationId
, submissionId
und caseId
.
Ohne Paging werden die ersten 500 Submissions geladen, siehe folgendes Beispiel:
var subscriberClient = ClientFactory.createSubscriberClient(config);
var destinationId= UUID.fromString("d2d43892-9d9c-4630-980a-5af341179b14");
Set<SubmissionForPickup> availableSubmissions = subscriberClient.getAvailableSubmissionsForDestination(destinationId);
Eine Submission abrufen
Mit der Methode requestSubmission
laden Sie eine abholbereite Submission (ReceivedSubmission
) inklusive der Fach- und Metadaten sowie der Attachments (falls vorhanden).
Sie können dieser Methode die submissionId
übergeben oder das Objekt SubmissionForPickup
:
// mittels submissionId
var submissionId = UUID.fromString("d2d43892-9d9c-4630-980a-5af341179b14");
ReceivedSubmission receivedSubmission = subscriberClient.requestSubmission(submissionId);
// mittels Objekt
SubmissionForPickup submissionForPickup = // abholbereite Submission
ReceivedSubmission receivedSubmission = subscriberClient.requestSubmission(submissionForPickup);
Das SDK prüft beim Abruf von Submission die erhaltenen Daten.
Zudem prüft das SDK, ob Token und Schlüssel gültig sind.
Schlägt eine Prüfung fehl, dann wird die Submission automatisch vom Verwaltungssystem zurückgewiesen.
Das bedeutet, dass ein REJECT
-Event an das Event-Log gesendet wird, mit der darauf folgenden Löschung der invaliden Submission.
Dieses Verhalten ist in den Umgebungen PROD, STAGE und TEST aktiv,
kann jedoch über die Eigenschaft enableAutoReject
in den Einstellungen des SDKs deaktiviert werden.
Zugriff auf Fach- und Metadaten
Sie können über die ReceivedSubmission
auf die Fach- und Metadaten sowie auf die Attachments einer Submission zugreifen,
nachdem die Submission geladen, entschlüsselt und erfolgreich validiert wurde:
// Zugriff auf Fachdaten
String data = receivedSubmission.getDataAsString();
URI dataSchemaUri = receivedSubmission.getDataSchemaUri();
String mimeType = receivedSubmission.getDataMimeType();
// Zugriff auf Metadaten
Metadata metadata = receivedSubmission.getSubmissionMetdata();
// Zugriff auf Rückkanal
ReplyChannel replyChannel = metadata.getReplyChannel();
// Zugriff auf Attachments
for( Attachment attachment : receivedSubmission.getAttachments()){
String originalFilename = attachment.getFilename();
String attachmentMimeType = attachment.getMimeType();
// Rohdaten des Attachments als byte[]
byte[] attachmentDataAsBytes = attachment.getDataAsBytes();
// Rohdaten des Attachments als String (per default UTF-8 encoded)
String attachmentDataAsString = attachment.getDataAString();
}
// Zugriff auf IDs
UUID caseId = receivedSubmission.getCaseId();
UUID submissionId = receivedSubmission.getSubmissionId();
UUID destinationId = receivedSubmission.getDestinationId();
Sofern Sie beabsichtigen die bidirektionale Kommunikation zu nutzen stellen Sie an dieser Stelle sicher, dass die Submission mit den Metadaten in Ihrer Anwendung gesichert werden, da hier sowohl die Verschlüsselungs-Keys als auch die zu nutzenden Prozessstandards angegeben werden. Diese Submission übergeben Sie später an die entsprechende Funktionen.
Zugriff auf große Attachments
Wenn der Sender (Onlinedienst) die Einreichung mit aktiviertem Attachment Chunking gesendet hat, kann der Empfänger auf Attachments zugreifen die aus einzelnen Fragmenten zusammengesetzt wurden (Large-Attachments). Dabei wird das resultierende Attachment im Dateisystem abgelegt, da die Daten u.U. nicht in den Hauptspeicher (RAM) passen.
Um Chunking zu nutzen, muss die Destination ein Metadatenschema in der Version >= 1.3.0 unterstützen.
Für den Zugriff auf die Datei eines großen Attachments, besitzt die Attachment
Klasse zwei Methoden, die im folgenden Beispiel dargestellt sind:
// (Optionale) Prüfung ob es sich um ein großes Attachment mit Daten im Dateisystem handelt
if(attachment.isLargeAttachment()){
// Zugriff auf das File als Stream
InputStream attachmentStream = attachment.getDataAsInputStream();
// Direkter Zugriff auf den Pfad im Dateisystem
Path largeFilePath = attachment.getLargeAttachmentFilePath();
...
}else{
// In-Memory Attachment das in den RAM geladen wird
byte[] attachmentData = attachment.getDataAsBytes();
...
}
Wird auf ein Large-Attachment dennoch über getDataAsBytes()
zugegriffen, sollte beachtet werden, dass Byte-Arrays
in Java eine max. Größe von 2 GB haben und die Daten evtl. nicht in den Speicher geladen werden können.
Dateisystem bereinigen
Um die Daten der Attachments, die im Dateisystem abgelegt wurden, zu bereinigen gibt es zwei Varianten:
Aufruf der delete()
-Methode auf dem File eines Attachments
Attachment largeAttachment = ....
largeAttachment.getLargeAttachmentFilePath().toFile().delete();
Clean-up Funktion des
Hier werden alle vom SDK erzeugten Ordner und Dateien aus dem AttachmentStorage-Pfad gelöscht:
var subscriber = ClientFactory.createSubscriberClient(config);
subscriber.clearAttachmentStorage();
Die vom SDK erzeugten Dateien sollten nur temporär genutzt werden. Für die Sicherung und Ablage, wird empfohlen diese (bspw. ins Fachverfahren) zu verschieben.
Submission Status abrufen
Sie rufen den Status einer Submission mit der Methode getSubmissionStatus
der Klasse SubscriberClient
ab:
SubscriberClient subscriberClient = ClientFactory.createSubscriberClient(config);
SubmissionForPickup submissionForPickup = ...
var destinationId = submissionForPickup.getDestinationId();
var caseId = submissionForPickup.getCaseid()
var submissionId = submissionForPickup.getSubmissionId()
Status submissionStatus = subscriberClient.getSubmissionStatus(destinationId, caseId, submissionId);
LOGGER.info("Current status for submission {} => {}", submissionId, submissionStatus.getStatus());
Das folgende Beispiel zeigt die Ausgabe des Status einer Submission, nachdem sie angelegt wurde:
Current status for submission 43cf7163-5163-4bc8-865e-be96e271ecc3 => submitted
Beim Statusabruf durch Verwaltungssysteme werden keine AuthenticationTags validiert. Diese sind nur auf der Onlinedienst-Seite verfügbar.
Das folgende Diagramm zeigt alle Zustandsübergänge einer Submission, vom Anlegen der Submission bis zur Abholung durch das Verwaltungssystem. Klicken Sie auf das Diagramm, um es zu vergrößern.
Empfangsbestätigung
Um eine Submission zu akzeptieren oder abzulehnen, kann der Verwaltungssystem-Client entsprechende Events an das Event-Log senden.
Weitere Details finden Sie in der Dokumentation zu Events und die Erzeugung von Security Event Tokens.
Submission akzeptieren
Nach der fachlichen Prüfung der Submission durch das Verwaltungssystem kann sie mit einem accept-submission
-Event angenommen werden.
Diesem Event können Sie Problems hinzufügen, die Anmerkungen ermöglichen und nicht zur Zurückweisung der Submission führen:
SubscriberClient subscriberClient = ClientFactory.createSubscriberClient(config);
var submissionId = UUID.fromString("d2d43892-9d9c-4630-980a-5af341179b14");
// Abholen der Submission mit allen Daten
ReceivedSubmission receivedSubmission = subscriberClient.requestSubmission(submissionId);
// Akzeptieren der Submission ohne die Angabe von Problems
receivedSubmission.acceptSubmission();
// Akzeptieren der Submission mit einer Liste von Problems
receivedSubmission.acceptSubmission(List.of(new MyCustomProblem()));;
Nach dem Senden des accept-submission
-Events wird die Submission in den Status deleted
überführt und im Zustelldienst gelöscht.
Submission zurückweisen
Fällt die fachliche Prüfung des Verwaltungssystems negativ aus,
wie zum Beispiel bei nicht entschlüsselbaren oder nicht schemakonformen Fachdaten, muss die Submission zurückgewiesen werden.
Die Zurückweisung erlaubt die Angabe von Problems aus der Domäne *.api.domain.model.event.problems.*
.
Weitere Details finden Sie unter den verfügbaren (technischen) Problemen.
SubscriberClient subscriberClient = ClientFactory.createSubscriberClient(config);
var submissionId = UUID.fromString("d2d43892-9d9c-4630-980a-5af341179b14");
// Abholen der Submission mit allen Daten
ReceivedSubmission receivedSubmission = subscriberClient.requestSubmission(submissionId);
// Senden der Zurückweisung mit einer Liste von Problemen
receivedSubmission.rejectSubmission(List.of(new DataSchemaViolation(), new MyCustomProblem("Angegebene Stadt existiert nicht")));
Nach Senden des reject-submission
-Events wird die Submission in den Status deleted
überführt und im Zustelldienst gelöscht.
Submission direkt zurückweisen
Wenn Sie eine oder mehrere Submissions direkt zurückweisen wollen,
ohne zuvor alle Daten zu laden,
dann können Sie diese Submissions auch über den SubscriberClient
zurückweisen:
SubscriberClient subscriberClient = ClientFactory.createSubscriberClient(config);
var destinationId = UUID.fromString("d2d43892-9d9c-4630-980a-5af341179b14");
Set<SubmissionForPickup> submissions = subscriberClient.getAvailableSubmissionsForDestination(destinationId);
// direkte Zurückweisung aller SubmissionForPickup ohne Laden weiterer Daten
submissions.forEach(submission -> subscriberClient.rejectSubmission(submission, List.of(new TechnicalProblem())))
Bidirektionale Kommunikation
FIT-Connect ermöglicht einen Dialog zwischen Onlinedienst und Verwaltungssystem,
sodass Onlinedienst und Verwaltungssystem direkt Nachrichten miteinander austauschen können.
Dieser Dialog wird Bidirektionale Kommunikation (BiDiKo) genannt.
Die Seite Onlinedienst beschreibt die bidirektionale Kommunikation und definiert wichtige Begriffe, wie Replys (Antworten des Verwaltungssystems auf Einreichungen von einem Onlinedienst).
Verwaltungssystem sendet Antwort über FIT-Connect
FIT-Connect ermöglicht einem Verwaltungssystem, eine Antwort (Reply) zu einer Einreichung an den Onlinedienst zurückzusenden. Der Onlinedienst kann auf die Antwort reagieren, indem er eine neue Einreichung an das Verwaltungssystem über FIT-Connect sendet.
Auf eine Submission antworten
Sie senden eine Antwort zu einer Einreichung (Submission) zurück,
indem Sie ein SendableReply
von dieser ReceivedSubmission
erzeugen (siehe folgendes Beispiel).
Alle Daten der erhaltenen Submission werden übernommen.
Die Fachdaten und Attachments können im Reply jedoch neu gesetzt werden.
Anschließend senden Sie die Antwort (Reply) mit der Methode SubscriberClient.sendReply(...)
an das Verwaltungssystem über FIT-Connect zurück:
ReceivedSubmission receivedSubmission = subscriberClient.requestSubmission(submissionId);
SendableReply sendableReply = SendableReply.from(receivedSubmission)
.setJsonData(getReplyJsonData(), URI.create("https://schema.fitko.de/fim/s00000114_1.1.schema.json"))
.addAttachment(Attachment.fromPath(Path.of("fitconnect/data/reply-attachment.txt"), "application/pdf"))
.build();
SentReply sentReply = subscriberClient.sendReply(sendableReply);
Das Zurücksenden einer Antwort über FIT-Connect ist nur dann möglich, wenn für die Submission, auf die geantwortet werden soll, FIT-Connect als Rückkanal gesetzt ist.
Um sicherzustellen das der neueste Verschlüsselungsschlüssel eines Case abgerufen wird, sollten zunächst alle Submissions eines Case geladen werden und nach dem submittedtAt
Zeitstempel der ReceivedSubmisssion
sortiert werden.
Die ReceivedSubmission
kann hierzu automatisch sortiert werden, da sie intern das Comparable
-Interface implementiert, welches bereits den Zeitstempel vergleicht.
Status einer Antwort abrufen
Sie erfragen den Status einer gesendeten Antwort (sentReply
),
indem Sie die Methode getReplyStatus
der Klasse SubscriberClient
aufrufen:
Status replyStatus = subscriberClient.getReplyStatus(sentReply);
assertThat(replyStatus.getStatus(), is(EventState.SUBMITTED));
Callbacks validieren
Beim Empfang von Callbacks
sollten Sie prüfen,
ob die empfangenen Daten gültig sind,
um unautorisierte Zugriffe auf Geschäftsprozesse und Nutzerdaten zu verhindern.
Die für die Validierung notwendigen Daten befinden sich innerhalb des empfangenen HTTP-Request
.
FIT-Connect nutzt das HMAC-Verfahren
, um die Gültigkeit des Aufrufs zu überprüfen.
Hierfür bietet das SDK die Methode validateCallback
der Klasse SubscriberClient
:
SubscriberClient subscriberClient = ClientFactory.createSubscriberClient(config);
ValidationResult validationResult = subscriberClient.validateCallback("hmac", 0L, "body", "secret");
if(validationResult.hasError()){
LOGGER.error(validationresult.getError().getMessage());
}
Weitere Details zur Funktionsweise von Callbacks finden Sie hier.