Skip to content
Snippets Groups Projects
Name Last commit Last update
.m2
doku
src
.gitignore
.gitlab-ci.yml
README.md
pom.xml

XTA-Client

Ein Client zum Senden und Empfangen von XTA Nachrichten.

Der Client verwendet XTA 2 Version 3.1 mit XTA-Modul-Webservice-Version 2.1.1. Er wird als Maven-Artefakt xta-client-lib bereitgestellt und kann in Java-Anwendungen eingebunden werden.

Senden einer Nachricht

Zum Senden einer Nachricht konfiguriert die Nutzer*in einen neuen XTA-Client mit einem Client-Zertifikat, welches sie für das Senden mit einer Autor-Kennung autorisiert.

Die Nutzer*in erstellt die zu sendende Nachricht mit entsprechender Autor- und Leser-Kennung. Anschließend übergibt sie die Nachricht an den XTA-Server mit einem Aufruf von XtaClient::sendMessage. Wenn der zurückgegebene Transport-Report den Status OPEN meldet, steht die Nachricht dem Leser zur Abholung bereit.

%% Senden einer Nachricht
  sequenceDiagram
    participant A as Nutzer*in
    participant B as XTA-Client
    participant C as XTA-Server
    Note left of A: (1) XTA-Client erzeugen
    Note left of A: (2) Nachricht erzeugen
    Note left of A: (3) Nachricht senden
    A->>B: sendMessage
    activate A
    activate B
    B->>C: checkAccountActive
    activate C
    C-->>B: 
    deactivate C
    B->>C: lookupService
    activate C
    C-->>B:  
    deactivate C
    B->>C: createMessageID
    activate C
    C-->>B: 
    deactivate C
    B->>C: sendMessage
    activate C
    C-->>B: 
    deactivate C
    B->>C: getTransportReport
    activate C
    C-->>B: 
    deactivate C
    B-->>A: 
    deactivate B
    deactivate A
    Note left of A: (4) Nachrichtenstatus prüfen

* Der XTA-Server wird oft als Nachrichtenbroker oder Nachrichtenvermittler bezeichnet.

Beispielcode:

// (1) XTA-Client erzeugen
var client = XtaClient.from(config);
// (2) Nachricht erzeugen
var zipFileName = "d5be7468-e620-4126-a40e-61a7f9b46345_Geschaeftsgang.Geschaeftsgang.0201.zip";
var zipFileContentDataHandler = new DataHandler(new FileDataSource("/path/to/" + zipFileName));
var xdomeaXtaFile = XtaFile.builder()
        .name(zipFileName)
        .content(zipFileContentDataHandler)
        .contentType("application/zip")
        .build();

var message = XtaMessage.builder()
        .metaData(XtaMessageMetaData.builder()
                .service("urn:xoev-de:xdomea:schema:2.4.0/xdomea240Antrag.wsdl")
                .businessScenarioCode("XDOMEAGAD_DATA")
                .businessScenarioListUri("urn:de:dataport:codeliste:business.scenario")
                .businessScenarioListVersionId("1.0")
                .messageTypeCode("Geschaeftsgang.Geschaeftsgang.0201")
                .messageTypePayloadSchema("urn:xoev-de:xdomea:schema:2.4.0")
                .authorIdentifier(XtaIdentifier.builder()
                        .category("Generischer Antragsdienst")
                        .value("gad:010200100000")
                        .build())
                .readerIdentifier(XtaIdentifier.builder()
                        .category("Generischer Antragsempfänger")
                        .value("gae:test-environment@ozg-cloud.de")
                        .build())
                .build())
        .messageFile(xdomeaXtaFile)
        .attachmentFiles(emptyList())
        .build();
// (3) Nachricht senden
var transportReport = client.sendMessage(message);
// (4) Nachrichtenstatus prüfen
assert transportReport.status() == XtaMessageStatus.OPEN;

Da eine Xdomea-Nachricht die Leser- und Autor-Kennung bereits enthält, ist es möglich aus der Xdomea-ZIP-Datei die Metadaten der XTA-Nachricht abzuleiten:

// ...
// (2) Nachricht erzeugen
// ...
var message = XdomeaXtaMessageCreator.createInstance().createMessage(xdomeaXtaFile);
// (3) Nachricht senden
var transportReport = client.sendMessage(message);
// ...

Hierbei wird die Xta-Autor-Kennung aus dem Xdomea-Absender-Kennung/Behoerdenschluessel gelesen und die Xta-Leser-Kennung aus dem Xdomea-Empfaenger-Kennung/Behoerdenschluessel.

Validierung der Xdomea-ZIP-Datei

Wenn eine XtaMessage für eine Xdomea-ZIP-Datei mit XdomeaXtaMessageCreator::createMessage erstellt wird, wird zudem geprüft, ob die Nachricht die "Transportfestlegungen Generischer Antragsdienst" einhält.

Für eine erfolgreiche Validierung muss eine Xdomea-ZIP-Datei folgende Bedingungen erfüllen:

  • Der ZIP-Dateiname ist <ProzessID>_<Nachrichtentyp>.zip (z.B. 00000000-0000-0000-0000-_Geschaeftsgang.Geschaeftsgang.0201.zip)
    • Die ProzessID in der Xdomea-Nachricht entspricht der ProzessID im Dateinamen
  • Die Xdomea-Nachricht <ProzessID>_<Nachrichtentyp>.xml in der ZIP-Datei ist schema-konform.
  • Der Xdomea-Nachrichten-Typ ist zulässig:
    • Geschaeftsgang.Geschaeftsgang.0201 mit Xdomea 2.4.0
    • Abgabe.Abgabe.0401 mit Xdomea 3.0.0
    • Abgabe.ImportBestaetigen.0402 mit Xdomea 3.0.0
  • Alle Dateien, die die Xdomea-Nachricht referenziert, sind in der ZIP-Datei enthalten.
  • Eine Absender-Kennung ist vorhanden mit dem Präfix gad
  • Eine Empfänger-Kennung ist vorhanden mit dem Präfix gae

Hinweis: Die Xdomea-Nachricht sollte mit UTF-8 kodiert sein.

Empfangen von Nachrichten

Zum Empfangen von Nachrichten konfiguriert die Nutzer*in einen neuen XTA-Client mit den gewünschten Leser-Kennungen. Zudem konfiguriert er das Client-Zertifikat, welches ihn zum Lesen mit den Leser-Kennungen autorisiert.

Beim Aufruf von fetchMessages werden alle Nachrichten für die Leser-Kennungen abgeholt und verarbeitet. Die Nachrichten-Verarbeitung erfolgt durch die übergebene processMessage-Funktion.

Nachdem alle Nachrichten verarbeitet sind, werden die Transport-Reports zurückgegeben.

Eine erfolgreich abgeholte/geschlossene Nachricht hat den Status RED, YELLOW oder GREEN. Hierbei signalisiert RED einen kritischen Fehler, YELLOW einen Warnhinweis und GREEN eine fehlerfreie Verarbeitung.

%% Empfangen von Nachrichten
  sequenceDiagram
    participant A as Nutzer*in
    participant B as XTA-Client
    participant C as XTA-Server
    Note left of A: (1) XTA-Client erzeugen
    Note left of A: (2) Nachrichten abholen
    A->>B: fetchMessages
    activate A
    activate B
    loop Für jede Leser-Kennung
        B->>C: checkAccountActive 
        activate C
        C-->>B: 
        deactivate C
        B->>C: getStatusList
        activate C
        C-->>B: 
        deactivate C
        loop Für jede ungelesene Nachricht
            B->>C: getMessage
            activate C
            Note left of B: Nachricht abholen
            C-->>B: 
            deactivate C
            B->>A: processMessage
	        deactivate B
            Note left of A: (3) Nachricht verarbeiten
            A-->>B: 
            activate B
            B->>C: close
            activate C
            Note left of B: Nachricht schließen
            C-->>B: 
            deactivate C
            B->>C: getTransportReport
            activate C
            C-->>B: 
            deactivate C
            B->>A: 
        end
	end
	deactivate B
	deactivate A
    Note left of A: (4) Nachrichtenstatus prüfen

* Sollte processMessage bei der Verarbeitung eine RuntimeException werfen, wird Nachrichten schließen übersprungen.

Hinweis: Nicht geschlossene Nachrichten mit Status OPEN werden beim nächsten Aufruf von fetchMessages erneut bearbeitet.

Beispielcode:

// (1) XTA-Client erzeugen
var client = XtaClient.from(config);
// (2) Nachrichten abholen
var transportReports = client.fetchMessages(xtaMessage -> {
    // (3) Nachricht verarbeiten
});
// (4) Nachrichtenstatus prüfen
for (var transportReport : transportReports) {
    assert transportReport.status() == XtaMessageStatus.GREEN;
}

Konfiguration

Der XTA-Client wird mit einer XtaClientConfig konfiguriert:

  • XTA-Service-Port-URLs: management, send und msgBox
  • Client-Zertifikat der Autor-Kennung (für sendMessage) und der Leser-Kennungen (für fetchMessages)
    • Leser-Client-Kennungen für fetchMessages.
  • ... siehe XtaClientConfig

Beispielcode:

var config = XtaClientConfig.builder()
        .managementServiceUrl("https://my-xta-server.de/MB_XTA-WS/XTA210managementPort.svc")
        .sendServiceUrl("https://my-xta-server.de/MB_XTA-WS/XTA210sendPort.svc")
        .msgBoxServiceUrl("https://my-xta-server.de/MB_XTA-WS/XTA210msgBoxPort.svc")
        .clientCertKeystore(XtaClientConfig.KeyStore.builder()
                .content(Files.toByteArray(new File("/path/to/client-cert.p12")))
                .type("PKCS12")
                .password("keystore-password")
                .bulid())
        .clientIdentifiers(List.of(
                XtaIdentifier.builder()
                        .category("Generischer Antragsempfänger")
                        .value("gae:test-environment@ozg-cloud.de")
                        .build(),
                XtaIdentifier.builder()
                        .category("Generischer Antragsempfänger")
                        .value("gae:dev-environment@ozg-cloud.de")
                        .build()
        ))
        .build();
var client = XtaClient.from(config);

Hinweis: Sollte die Root-CA des XTA-Servers nicht für das Ziel-System konfiguriert sein, muss zudem ein entsprechender XtaClientConfig::trustStore konfiguriert werden.

Filterung von Nachrichten vor der Abholung

Um Nachrichten vor dem Abholen basierend auf XtaMessageMetadata zu filtern, sollte das optionale Predicate<XtaMessageMetadata> für XtaClientConfig::isMessageSupported konfiguriert werden. Zum Beispiel kann auf diese Weise verhindert werden, dass nicht unterstützte Nachrichten, die unausweichlich zu einem Verarbeitungsfehler führen, vollständig heruntergeladen werden müssen.

Referenzen