Zum Hauptinhalt springen

Java-SDK

Onlinedienst implementieren

Sendende Systeme übertragen Anträge (Submissions) über FIT-Connect an einen Empfänger. Das Senden von Anträgen ist auf der Seite Versand von Einreichungen beschrieben.

Das Java-SDK setzt Details wie Validierungen und Verschlüsselung intern um, sodass Sie sich bei der Anbindung auf die Implementierung der Schnittstelle fokussieren können.

Die folgende Beschreibung zeigt, wie Sie mit dem Java-SDK eine Submission erzeugen und an einen Zustellpunkt senden. Zudem wird gezeigt, wie Sie die bidirektionale Kommunikation (BiDiKo) in FIT-Connect verwenden.

Konfiguration erstellen

Für die Implementierung eines Onlinedienstes 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 einen Onlinedienst in diese Datei eintragen.

Java YAML
var config = ApplicationConfig.builder()
.senderConfig(new SenderConfig("clientId", "clientSecret"))
.activeEnvironment(Environments.TEST.getEnvironmentName())
.build();
senderConfig:
clientId: "clientId"
clientSecret: "clientSecret"
activeEnvironment: TEST

Die YAML Konfiguration wird mit dem ApplicationConfigLoader geladen werden, wie das folgende Beispiel zeigt:

ApplicationConfigLoader.loadConfigFromPath(Path.of("/path/to/config"))

Client für Onlinedienst erstellen

Im nächsten Schritt wird ein SenderClient benötigt, der mittels der ClientFactory erzeugt werden kann.

SenderClient senderClient = ClientFactory.createSenderClient(config);

Submission erzeugen und senden

Das Java-SDK kann im Umfeld einer Webapplikation im Backend eingesetzt werden. Bei diesem Anwendungsfall können die Daten sowohl verschlüsselt (zum Beispiel über das JavaScript-SDK, noch in Entwicklung) als auch unverschlüsselt vom Browser an das Java-SDK im Backend übergeben werden. Überträgt das Frontend Antragsdaten unverschlüsselt an das Backend, dann verschlüsselt das Java-SDK intern die Daten und überträgt diese über FIT-Connect an das adressierte Verwaltungssystem.

Für die Erstellung einer Submission stehen daher zwei Builder bereit, um alle notwendigen Daten zu setzen:

  • SendableEncryptedSubmission.Builder() für Submissions mit bereits verschlüsselten Daten
  • SendableSubmission.Builder() für Submissions mit noch nicht verschlüsselten Daten
Zustellpunkt finden

Liegt Ihnen die destinationId nicht vor, dann können Sie sie mithilfe des RoutingClient über findDestinations erfragen.

Bereits verschlüsselte Daten senden

Werden die Antragsdaten bereits vom Endgerät der Anwender:in verschlüsselt, dann ist eine Ende-zu-Ende-Verschlüsselung möglich und die Antragsdaten liegen im Backend des Onlinedienstes (des Onlinedienstes) verschlüsselt vor. Das Backend des Onlinedienstes (das Java-SDK) hat dabei keinen Einblick in die Klardaten.

Zur Verschlüsselung von Antragsdaten im Frontend eines Onlinedienstes (im Browser der Antragsteller:in) kann das JavaScript-SDK von FIT-Connect genutzt werden. Das JavaScript-SDK benötigt für die Verschlüsselung der Antragsdaten den PublicKey des Zustellpunktes, an den der Antrag über FIT-Connect gesendet werden soll. Das JavaScript-SDK im Frontend kann jedoch nicht direkt den PublicKey vom Zustelldienst abrufen. Dafür benötigt es die Hilfe des Backends (des Java-SDKs).

Deshalb müssen Sie im Backend des Onlinedienstes den PublicKey vom Zustelldienst abrufen und für die Abfrage durch das JavaScript-SDK (durch das Frontend) zur Verfügung stellen. Das folgende Beispiel ruft den öffentlichen Schlüssel einer Destination (eines Zustellpunktes) ab.

Die Validierung des öffentlichen Schlüssels erfolgt automatisch durch das Java-SDK gemäß der kryptographischen Vorgaben. Weitere Informationen zur Ende-zu-Ende-Verschlüsselung finden Sie auf der Seite Verschlüsselte Übertragung von Antragsdaten.

Schritte zur Übertragung verschlüsselter Daten

1. Public Key abrufen und für das Frontend zur Verfügung stellen

Sie rufen den PublicKey eines Zustellpunkts (einer Destination) mit der Methode getPublicKeyForDestination des Onlinedienst-Clients ab:

SenderClient senderClient = ClientFactory.createSenderClient(config);

// Demo-Destination
var destinationId = UUID.fromString("d2d43892-9d9c-4630-980a-5af341179b14");

String publicJwkAsJsonString = senderClient.getPublicKeyForDestination(destinationId);

Das Frontend des Onlinedienstes ruft nun den öffentlichen Schlüssel vom Backend ab. Dafür müssen die Entwickler:innen des Onlinedienstes eine entsprechende Funktion implementieren.

Mit dem PublicKey des Zustellpunktes verschlüsselt das Frontend des Onlinedienstes die Antragsdaten und sendet die Daten verschlüsselt an das Backend.

Auf der Seite SDKs - Übersicht finden Sie eine Beschreibung des Zusammenspiels von Front- und Backend.

2. Submission für verschlüsselte Daten erstellen und senden

Sie verwenden den SendableEncryptedSubmission.Builder, um eine Submission für verschlüsselte Daten zu erstellen. Bei der Angabe der (optionalen) Attachments muss die UUID für jedes Attachment vom Frontend zur Verfügung gestellt werden. Dies ist notwendig, da das SDK die Attachments (Anhänge) zunächst beim Zustelldienst ankündigen muss, jedoch keinen Zugriff auf die verschlüsselten (Meta-) Daten hat, die die IDs der Attachments enthalten.

SenderClient senderClient = ClientFactory.createSenderClient(config);

SendableEncryptedSubmission encryptedSubmission = SendableEncryptedSubmission.Builder()
.setDestination(UUID.fromString("d2d43892-9d9c-4630-980a-5af341179b14"))
.setServiceType("urn:de:fim:leika:leistung:99900000000000", "FIT-Connect Demo")
.setEncryptedMetadata("$encrpyt€ed metadata")
.setEncryptedData("{$encrpyt€ed json}")
// optional
.addEncryptedAttachment(UUID.fromString("d2d43892-9d9c-4630-980a-5af341179b14"), "$encrpyt€ed @tt@chment")
.build();

SentSubmission sentSubmission = senderClient.send(encryptedSubmission);
Hinweis

Wenn die destinationId und der serviceIdentifier (im Beispiel oben urn:de:fim:leika:leistung:99900000000000) vom Frontend bereitgestellt werden, dann prüft das SDK, ob der angegebene Service-Typ an der spezifischen Destination erlaubt ist.

Noch nicht verschlüsselte Daten senden

Sie übergeben der Methode SendableSubmission.Builder() unverschlüsselte Daten, die dann intern verschlüsselt werden. Wenn das Frontend Antragsdaten unverschlüsselt an das Backend sendet, dann können Sie die Antragsdaten im Backend mit SendableSubmission.Builder() in ein verschlüsseltes Submission-Objekt umwandeln und verschlüsselt über FIT-Connect an das adressierte Verwaltungssystem (Subscriber) übertragen.

SenderClient senderClient = ClientFactory.createSenderClient(config);

SendableSubmission sendableSubmission = SendableSubmission.Builder()
.setDestination(UUID.fromString("d2d43892-9d9c-4630-980a-5af341179b14"))
.setServiceType("urn:de:fim:leika:leistung:99900000000000", "FIT Connect Demo")
.setJsonData("{\"message\":\"Hello World\"}", URI.create("https://schema.test.dev/submission-schema.json"))
// optional
.addAttachment(Attachment.fromPath(Path.of("path/to/attachment.txt"), "text/plain"))
.setReplyChannel(ReplyChannel.fromEmail("test@mail.org"))
.build();

SentSubmission sentSubmission = senderClient.send(sendableSubmission);
Hinweis

Diese Umsetzungsvariante bietet eine geringere Sicherheit als die Umsetzung der Ende-zu-Ende-Verschlüsselung ab dem Endgerät (Webbrowser) der Antragsteller:in. Zudem steigen die Anforderungen an die IT-Sicherheit und den Datenschutz, da Antragsdaten im Klartext durch das Backend des Onlinedienstes verarbeitet werden.
Eine Alternative stellt die Verschlüsselung von Antragsdaten im Frontend des Onlinedienstes dar (siehe Abschnitt Verschlüsselte Daten übertragen).

Übertragung großer Attachments

Metadatenversion

Um Chunking zu nutzen, muss die Destination ein Metadatenschema in der Version >= 1.3.0 unterstützen.

Sollen große Anhänge übertragen werden, die über das Limit von 500 MB für ein Attachment hinausgehen oder die Daten des Attachments nicht in den Arbeitsspeicher (RAM) passen, kann dass Chunking des SDKs verwendet werden. Hierbei wird ein großer Anhang, der einzeln nicht übertragen werden könnte, in kleinere Teile (Fragmente) zerlegt und an den Zustelldienst übertragen. Beim Empfänger (Subscriber) werden die Fragmente wieder zum ursprünglichen Attachment zusammengesetzt. Das Chunking kann ohne weitere Konfiguration über die Attachment-Methode fromLargeAttachment() verwendet werden:

Attachment.fromLargeAttachment(attachmentPath, "application/octet-stream", "large-file.bin", "large file");

Alle weiteren Varianten eines Attachments halten die Daten komplett im RAM. Der Vorteil bei der Verwendung eines Large-Attachments ist eine ressourcensparende Verarbeitung, da jeweils nur ein Chunk in den Speicher geladen, verschlüsselt und übertragen wird.

Chunking für In-Memory Attachments

Die Option chunkAllAttachments ermöglicht das Chunking auch für In-Memory Attachments, siehe Chunking Optionen

Methode Attachment-Typ Daten im Hauptspeicher
Attachment.fromLargeAttachment()Largedie Daten eines Fragments (z.B. 10MB mit Chunk-Size von 10MB)
Attachment.fromPath()In-Memorygesamtes Attachment (bis max. 2GB)
Attachment.fromByteArray()In-Memorygesamtes Attachment (bis max. 2GB)
Attachment.fromInputStream()In-Memorygesamtes Attachment (bis max. 2GB)

Bei der Nutzung von Large-Attachments werden die Daten als Stream aus dem Filesystem geladen und während des Chunkings in Fragmente zerteilt, die anschließend einzeln an den Zustelldienst übertragen werden. Innerhalb des Metadatensatzes wird hierbei das Fragments Array innerhalb der Content-Structure eines Attachments genutzt, welches dem Empfänger des fragmentierten Attachments ermöglicht dieses wieder zusammenzusetzen. Die Daten der Fragmente werden wie herkömmliche Attachments angekündigt und übertragen.

Limitierungen für Attachments und Fragmente
  • max. 100 Attachments/Fragmente pro Submission (oder Reply)
  • max. 500 MB für einzelne Fragmente oder Attachments
  • max. 2 GB für die absolute Größe aller Attachments/Fragmente einer Submission (oder Replies)

Beispiel einer Datei mit 1 GB bei einer Chunk-Size von 100 MB

Attachment Chunks im Dateisystem

Die Fragmente werden nach dem Chunking zunächst im Dateisystem zwischengespeichert. Ist in der AttachmentChunkingConfig kein anderes Verzeichnis angegeben, speichert das SDK die Daten im Ordner fit-connect-attachments im temporären Systempfad java.io.tmpdir. Nach dem Upload an den Zustelldienst werden die Fragmente wieder autom. aus dem Dateisystem entfernt. Für weitere Konfigurationsoptionen, siehe Abschnitt Chunking Optionen

Chunking Optionen

Java YAML
var chunkingConfig = AttachmentChunkingConfig.builder()
.chunkSizeInMB(10)
.chunkAllAttachments(true)
.attachmentStoragePath(Path.of("/custom/path"))
.build();
attachmentChunkingConfig:
chunkSizeInMB: 10
chunkAllAttachments: true
attachmentStoragePath: "/custom/path"

OptionBeschreibung
chunkSizeInMBAngabe der Größe eines einzelnen Attachment Fragments in MB (default: 50 MB, max: 350 MB)
chunkAllAttachmentsChunking auch für In-Memory Attachments (für Large-Attachments ist Chunking immer aktiviert)
attachmentStoragePathAblageort für Attachment Fragmente die während des Chunkings und beim Empfang erzeugt werden. (default ist fit-connect-attachments im temporären Systemverzeichnis java.io.tmpdir.

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 Clients

Hier werden alle vom SDK erzeugten Ordner und Dateien aus dem AttachmentStorage-Pfad gelöscht:

var sender = ClientFactory.createSenderClient(config);
sender.clearAttachmentStorage();

Submission Status abfragen

Nach der Einreichung einer Submission können Sie den aktuellen Status aus dem Event-Log mit getSubmissionStatus abfragen:

SenderClient senderClient = ClientFactory.createSenderClient(config);
SentSubmission sentSubmission = senderClient.send(submission);

Status submissionStatus = senderClient.getSubmissionStatus(sentSubmission);

LOGGER.info("Current status for submission {} => {}", sentSubmission.getSubmissionId(), submissionStatus.getStatus());

Das folgende Beispiel zeigt die Ausgabe des aktuellen Status einer Submission, nachdem sie angelegt wurde:

Current status for submission 43cf7163-5163-4bc8-865e-be96e271ecc3 => submitted

Das folgende Diagramm zeigt alle Zustandsübergänge einer Submission, vom Anlegen der Submission bis zur Abholung durch den Empfänger. Klicken Sie auf das Diagramm, um es zu vergrößern.

Status

Bidirektionale Kommunikation (BiDiKo)

Dialog zwischen Onlinedienst und Verwaltungssystem

Nach dem Versenden der ersten Submission ist in FIT-Connect ein direkter Dialog zwischen Onlinedienst und Verwaltungssystem möglich, wenn Sie die Bidirektionale Kommunikation (BiDiKo) verwenden.

Bei BiDiKo tauschen Onlinedienst und Verwaltungssystem direkt Nachrichten miteinander aus:

  • Der Onlinedienst sendet einen Antrag (auch Einreichung oder Submission genannt) über FIT-Connect an den Empfänger mit den für die Bidirektionale Kommunikation notwendigen Informationen. Der Onlinedienst wird im SDK auch Onlinedienst-Client genannt.
  • Der Empfänger antwortet auf diese Einreichung, indem er eine Nachricht über FIT-Connect an den Onlinedienst zurücksendet. Diese Rücksendung kann zum Beispiel ein Bescheid oder eine Rückfrage zum eingereichten Antrag sein. Die Rücksendung des Empfängers wird als Antwort oder Reply bezeichnet. Der Empfänger wird im SDK auch Subscriber oder Subscriber-Client genannt.
  • Der Onlinedienst kann nun auf die Antwort reagieren und eine neue Einreichung an den Empfänger senden. Alle Einreichungen als auch alle dazugehörigen Antworten (Replies) werden über dieselbe Vorgangsnummer (Case-ID) identifiziert. Über diesen Bezug auf diese Case-ID können nun beide Parteien beliebig oft und in beliebiger Reihenfolge Nachrichten versenden.

Um die BiDiKo zu nutzen, verwenden Sie FIT-Connect als Rückkanal (ReplyChannel):
Rufen Sie am SendableSubmission.Builder() die Methode setReplyChannel(...) auf und setzen Sie den ReplyChannel auf ReplyChannel.fromFitConnect() (siehe Beispiel weiter unten zum SendableSubmission.Builder).

Schlüsselpaar erzeugen

Um dem Empfänger (z. B. einem Verwaltungssystem) die Möglichkeit zu geben, Antworten (Replies) zu verschlüsseln, müssen Sie im ReplyChannel einen öffentlichen Verschlüsselungsschlüssel übergeben. Der Empfänger muss diesen öffentlichen Schlüssel verwenden, um die Antworten zu verschlüsseln.
Sie können den öffentlichen Schlüssel mit der Utility-Klasse ReplyChannelKeyGenerator erzeugen (Für den Rückkanal ist kein V-PKI Zertifikat notwendig). Der Key-Generator generiert ein Schlüsselpaar mit einem öffentlichen Verschlüsselungsschlüssel und dem dazugehörigen privaten Entschlüsselungsschlüssel. Der private Schlüssel diese Schlüsselpaars wird vom Onlinedienst (z. B. einem Onlinedienst) benötigt, um die Replies des Empfängers zu entschlüsseln. Sie sollten ein Schlüsselpaar für die Dauer eines Vorgangs (Case) beibehalten. Das Schlüsselpaar sollte nur bei sicherheitskritischen Vorfällen geändert werden.

// Onlinedienst erzeugt Schlüsselpaar (einmal pro Case)
JWKPair jwkPair = ReplyChannelKeyGenerator.generateKeyPair();
// Der private Schlüssel wird vom Onlinedienst sicher verwahrt
JWK privateReplyDecryptionKey = jwkPair.getPrivateKey();
// Der öffentliche schlüssel wird vom Empfänger (Verwaltungssystem) genutzt um den Reply zu verschlüsseln
JWK publicReplyEncryptionKey = jwkPair.getPublicKey();
Einsatz der generierten Keys

Sie können Schlüssel, die Sie mit ReplyChannelKeyGenerator erzeugen, nicht bei der Einrichtung eines Zustellpunktes verwenden, da sie nicht auf einem Zertifikat der V-PKI basieren. Es handelt sich hierbei um sogenannte Ephemeral Keys, die nur zum Ver- und Entschlüsseln von Replies innerhalb eines Vorgangs eingesetzt werden.

Nachdem Sie ein Schlüsselpaar erzeugt haben, fügen Sie den öffentlichen Schlüssel dem ReplyChannel hinzu: ReplyChannel.fromFitConnect(publicReplyEncryptionKey...) (siehe folgendes Beispiel).

Submission einem Vorgang zuordnen

Sie setzen bei allen Einreichungen (Submissions), die zu einem Vorgang gehören, dieselbe Vorgangsnummer (Case-ID) aus der ersten Vorgangsübermittlung. Das folgende Beispiel verwendet die Vorgangsnummer existingCaseId eines bestehenden Vorgangs, um eine neue Submission diesem Vorgang (Case) hinzuzufügen.

Sie müssen dem replyChannel den zuvor generierten publicKey mitgeben und auch den zulässigen Prozessstandard für den Rückkanal definieren. Im Anschluss kann die Submission über den SenderClient gesendet werden:

ReplyChannel replyChannel = ReplyChannel.fromFitConnect(publicReplyEncryptionKey, List.of("urn:xoev-de:bmk:standard:xbau_2.3"))

// Die caseId für einen bestehenden Vorgang kann von einer bereits gesendeten Submission bezogen werden
UUID existingCaseId = sentSubmission.getCaseId();

SendableSubmission sendableSubmission = SendableSubmission.Builder()
.setDestination(UUID.fromString("d2d43892-9d9c-4630-980a-5af341179b14"))
.setServiceType("urn:de:fim:leika:leistung:99900000000000", "FIT Connect Demo")
.setJsonData("{\"message\":\"Hello World\"}", URI.create("urn:xoev-de:bmk:standard:xbau_2.2#baugenehmigung.antrag.0200"))
// hinzufügen der neuen Submission zu einem bestehenden Vorgang
.setCaseId(existingCaseId)
// wird für die FIT-Connect Reply-Channel Kommunikation benötigt
.setReplyChannel(replyChannel)
.build();

SentSubmission sentSubmission = ClientFactory.createSenderClient(config).send(sendableSubmission);

Abholbereite Replies erfragen

Das Laden von Replies erfolgt in zwei Schritten.

  • Erfragen, ob abholbereite Replies vorliegen
  • Abholen eines bestimmten Replys

Um zu erfragen, ob Replys auf FIT-Connect vorliegen, rufen Sie die Methode getAvailableReplies auf:

SenderClient senderClient = ClientFactory.createSenderClient(config);

// Abrufen der ersten 500 Replies
RepliesForPickup repliesForPickup = senderClient.getAvailableReplies();

// Abrufen der ersten 25 Replies mit Pagination
var limit = 25;
var offset = 0;
RepliesForPickup repliesForPickup = senderClient.getAvailableReplies(limit, offset);

Callback für Replies

Alternativ zur Methode getAvailableReplies können Sie einen Callback verwenden, eine Webadresse, die das Backend Ihres Onlinedienstes (z. B. Onlinedienstes) bereitstellt. FIT-Connect ruft dann diesen Callback auf, um darüber zu informieren, dass eine Antwort (Reply) abgeholt werden kann.

Einen Reply abrufen

Mit der Methode getReply (siehe folgendes Beispiel) laden Sie einen abholbereiten Reply (ReceivedReply) inklusive der Fach- und Metadaten sowie der Anhänge (Attachments), falls Anhänge vorhanden sind. Sie übergeben dieser Methode die replyId der zu ladenden Reply und den privaten Entschlüsselungsschlüssel, den Sie vor dem Senden der zugehörigen Einreichung (Submission) erzeugt haben. Der private Schlüssel dient zum Entschlüsseln der Reply. Das Kapitel Schlüsselpaar erzeugen beschreibt das Erzeugen des öffentlichen Verschlüsselungsschlüssels und des privaten Entschlüsselungsschlüssels.

UUID replyId = replyForPickup.getReplyId();
// Key zum Entschlüsseln wird vom Onlinedienst gespeichert und muss beim Abholen von Replies zur Verfügung stehen
JWK privateReplyDecryptionKey = getPrivateReplyDecryptionKey();

ReceivedReply receivedReply = senderClient.getReply(replyId, privateReplyDecryptionKey);

Hinweis

Das SDK prüft beim Abruf von Replies die erhaltenen Daten.
Schlägt eine Prüfung fehl, dann wird der Reply automatisch vom SDK zurückgewiesen. Das bedeutet, dass ein REJECT-Event in das Event-Log eingetragen wird, mit der darauf folgenden Löschung des invaliden Replys.
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 den ReceivedReply auf die Fach- und Metadaten sowie auf die Attachments des Replys zugreifen, nachdem der Reply geladen, entschlüsselt und erfolgreich validiert wurde:

 // Zugriff auf Fachdaten
String data = receivedReply.getDataAsString();
URI dataSchemaUri = receivedReply.getDataSchemaUri();
String mimeType = receivedReply.getDataMimeType();

// Zugriff auf Metadaten
Metadata metadata = receivedReply.getSubmissionMetdata();

// Zugriff auf Rückkanal
ReplyChannel replyChannel = metadata.getReplyChannel();

// Zugriff auf Attachments
for(Attachment attachment : receivedReply.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 = receivedReply.getCaseId();
UUID submissionId = receivedReply.getSubmissionId();
UUID destinationId = receivedReply.getDestinationId();

Empfangsbestätigung für Replies

Um einen Reply zu akzeptieren oder abzulehnen, sendet der Onlinedienst entsprechende Events an das Event-Log (siehe folgende Beispiele fürs Akzeptieren und Ablehnen).

Event Log

Weitere Details finden Sie in der Dokumentation zu Events und zum Erzeugen von Security Event Tokens.

Reply akzeptieren

Nach der Prüfung durch den Onlinedienst (Sender-Client) können Sie den Reply mit einem accept-reply-Event annehmen. Sie können diesem Event Problems hinzufügen, die als Anmerkungen zu sehen sind, die nicht zur Zurückweisung des Replys führen:

// Akzeptieren des Replys ohne Angabe von Problems
receivedReply.acceptReply();

// Akzeptieren des Replys mit einer Liste von Problems
receivedReply.acceptReply(List.of(new MyCustomProblem());
Hinweis

Nach dem Senden des accept-reply-Events wird der Reply in den Status deleted überführt und im Zustelldienst gelöscht.

Reply zurückweisen

Wenn die Prüfung durch den Onlinedienst (Sender-Client) negativ ausfällt, zum Beispiel bei einer semantischen Unstimmigkeit in den Fachdaten (Städtename ist nicht real, Alter der Person ist nicht plausibel), dann kann der Reply 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.

// Senden der Zurückweisung mit einer Liste von Problemen
receivedReply.rejectReply(List.of(new DataSchemaViolation(), new MyCustomProblem("Angegebene Stadt existiert nicht")));

Nach Senden des reject-reply-Events wird der Reply in den Status deleted überführt und im Zustelldienst gelöscht.

Routing-Informationen

Der folgende Abschnitt zeigt, wie Sie die DestinationID des Zustellpunktes für eine bestimmte Verwaltungsleistung in einem bestimmten Gebiet ermitteln.

Hinweis

Es können mehrere Zustellpunkte (unterschiedliche destinationID) und auch mehrere Zustelldienste (unterschiedliche submissionUrl) für eine bestimmte Verwaltungsleistung in einem bestimmten Gebiet zuständig sein.

Sie können folgendermaßen vorgehen:

  1. Nach der AreaID für ein Gebiet suchen, mit der Methode findAreas der Klasse RouterClient.
  2. Suchanfrage erzeugen mit der Klasse DestinationSearch.Builder.
  3. Nach den DestinationIDs suchen, mit der Methode findDestinations der Klasse RouterClient, mit dem Parameter AreaID, AGS oder ARS

Nach der AreaID für ein Gebiet suchen

Die AreaIDs für Gebiete können mit einem oder mehreren Kriterien gesucht werden. Das folgende Beispiel sucht die AreaIDs anhand des Städtenamens (mit Wildcard *) und der Postleitzahl:

RouterClient routerClient = ClientFactory.createRouterClient(config);

var citySearchCriterion = "Leip*";
var zipCodeSearchCriterion = "04229";

// finde die ersten fünf Resultate
List<Area> areas = routerClient.findAreas(List.of(citySearchCriterion, zipCodeSearchCriterion), 0, 5);

LOGGER.info("Found {} areas", areas.size());
for (Area area : areas){
LOGGER.info("Area {} with id {} found", area.getName(), area.getId());
}

Suchanfrage erzeugen mit dem DestinationSearch.Builder.

Um eine Suchanfrage zu erzeugen, verwenden Sie die Klasse DestinationSearch.Builder

Für die Suchanfrage benötigen Sie den Leistungsschlüssel leikaKey und genau ein Suchkriterium für die Region:

Ein Suchkriterium für die Region kann sein:

Leistungsschlüssel

Sowohl der leikaKey, als auch die Regionalschlüssel ars und ags können nicht über den RoutingClient bezogen werden. Hierfür können Sie folgende Quellen nutzen:

Nach der DestinationID suchen, mit der AreaID

RouterClient routerClient = ClientFactory.createRouterClient(config);

DestinationSearch search = DestinationSearch.Builder()
.withLeikaKey("99123456760610")
.withAreaId("48566") // areaId der Stadt "Leipzig"
.withLimit(3)
.build();

// Finde die ersten drei Resultate
List<Route> routes = routerClient.findDestinations(search);

LOGGER.info("Found {} routes for service identifier {}", routes.size(), leikaKey);
for (Route route : routes){
LOGGER.info("Route {} with destinationId {} found", route.getName(), route.getDestinationId());
}

Nach der DestinationID suchen, mit ARS oder AGS

Als Suchkriterium können Sie auch den Amtlichen Regionalschlüssel ARS oder den Gebietsschlüssel AGS verwenden. Das folgende Beispiel nutzt den ARS:

RouterClient routerClient = ClientFactory.createRouterClient(config);

DestinationSearch search = DestinationSearch.Builder()
.withLeikaKey("99123456760610")
.withArs("147130000000") // beispiel ARS für "Leipzig"
.withLimit(3)
.build();

// Finde die ersten drei Resultate
List<Route> routes = routerClient.findDestinations(search);

LOGGER.info("Found {} routes for service identifier {}", routes.size(), leikaKey);
for (Route route : routes){
LOGGER.info("Route {} with destinationId {} found", route.getName(), route.getDestinationId());
}

Callbacks validieren

Beim Empfang von Callbacks sollte der Onlinedienst 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 eines Aufrufs zu überprüfen.

Hierfür bietet das SDK die Methode validateCallback der Klasse SenderClient:

SenderClient senderClient = ClientFactory.createSenderClient(config);

ValidationResult validationResult = senderClient.validateCallback("hmac", 0L, "body", "secret");

if(validationResult.hasError()){
LOGGER.error(validationresult.getError().getMessage());
}
Hinweis

Weitere Details zur Funktionsweise von Callbacks finden Sie auf der Seite Verwendung von Callbacks.