Der B2B Message Service gehört zum B2B System. Er ist nicht Teil des AS4 Systems.
Der B2B Message Service kann asynchron per AMQP an ein AS4 System angeschlossen werden.
- AS4 Outbound: Über die weitere REST Schnittstelle (/messages) kann der Service nach korrektem B2B-Customizing die messageId und attributeId einer von der B2B ausgehenden Edifact empfangen. Diese wird über eine interne Queue weitergeleitet zu einem im selben Service liegendem Consumer, welcher die Edifact aus der Datenbank lädt und diese über den Message Broker an den Translator Service weiterleitet. Nachdem das AS4-System die Nachricht an den Marktpartner gesendet hat, empfängt die Anwendung über eine weitere AMQP Schnittstelle Informationen über AS4 Nachricht und Quittung vom AS4-System, speichert diese in der B2B- Datenbank und setzt den Verarbeitungsstatus und Bestätigungsstatus entsprechend.
- AS4 Inbound: Der Service empfängt eine Edifact Nachricht inklusive weiterer Informationen über den AS4-Versand und die Quittung per AMQP und übergibt diese an die B2B Queue (Datenbank) zur weiteren Verarbeitung durch die B2B. Basierend auf den weiteren Informationen werden Verarbeitungsstatus, Bestätigungsstatus und Channel gesetzt.
- AS4 Pathswitch Delivery: Der Service kann auch Pathswitch-Informationen vom AS4-System emfpangen und an das B2B-System weiterleiten, damit das b2B-System weiß, ob zwischen zwei Markpartnern eine Kommunikation über AS4 besteht oder nicht.
Der B2B Message Service kann asynchron per AMQP Edifact Nachrichten empfangen & verschicken (unabhängig von AS4).
- Edifact Empfang: Der Service kann eine Edifact per AMQP empfangen und dem B2B Workflow übergeben.
- Edifact Versand: Der Edifact Versand kann über die gleiche Schnittstelle wie AS4 Outbound Workflow erfolgen.
Hardwareanforderungen
Eine Service-Instanz erfordert mindestens 512 MB RAM.
Wir empfehlen 0,4 CPU-Kerne je Instanz.
Logs werden auf die Festplatte geschrieben, entsprechend muss genügend Speicherplatz vorhanden sein.
Abhängigkeiten
Der Service greift auf einen Message-Broker zu, um Nachrichten zu empfangen und zu versenden.
Der Service greift auf eine SQL Datenbank zu, um Nachrichten zu speichern. Hierbei handelt es sich um die gleiche Datenbank, die auch von der B2B genutzt wird. Der Speicherverbrauch einer B2B Datenbank ist hoch. Er skaliert mit dem Nachrichtenaufkommen und hängt von der Archivierungs-/Löschstrategie ab.
Prozesse
Der B2B-Message-Service unterstützt folgende Prozesse:
- as4-inbound
- as4-outbound & receipt
- as4-pathswitch
- passthrough
- edifact
Im Folgenden ist mit B2B-Tomcat ein B2B Knoten des B2B-Monolithen gemeint. Das B2B System hingegen bezeichnet das Zusammenspiel der B2B-Knoten und des B2B-Message-Service.
Im Folgenden beziehen sich Exchange und Queue auf den AMQP-Message-Broker. Der Queue-Service der B2B hingegen bezieht sich auf die SQL Datenbank der B2B.
as4-inbound
Beim AS4-Inbound-Prozess durchläuft eine eingehende AS4-Nachricht den B2B-Inbound-Workflow. Dieser Workflow ermöglicht das Monitoring der Nachricht. Im Standard führt die B2B außerdem eine Validierung der Marktnachricht durch inklusive der zugehörigen Folgeschritte (z.B. Generierung von Contrl/Aperak, falls es sich bei der Marktnachricht um eine Edifact handelt). Am Ende des B2B-Inbound-Workflows wird die Nachricht an das Backend (z.B. AEP-Mako-Cloud) übergeben.
Das AS4-System überträgt eine eingehende AS4-Nachricht samt Quittung (falls vorhanden) und entschlüsselter Marktnachricht über die Exchange
as4.inbound
. Der B2B-Message-Service holt die Nachricht in der zugehörigen Queue ab (1). Er speichert sie in der SQL-Datenbank der B2B (
2). Der B2B-Queue-Service im B2B-Tomcat crawlt die Datenbank (3) und stößt den B2B-Workflow für die Nachricht an. Am Ende des B2B-Workflows
wird die Nachricht an das Backend (z.B. AEP-Mako-Cloud) übergeben (4).
as4-outbound
Der folgende Abschnitt ist Deprecated. Statt einer fehleranfälligen Anbindung via REST bieten wir nun die Übertragung via B2B-Outbox an. Nutzen Sie eine Kombination aus der B2B-Outbox und der AS4-Outbound-Payload-Json-Creator-Action. Zuerst wird der Outbound-Payload generiert und dann per Outbox verschickt.
Ziel des AS4-Outbound-Prozesses ist es, eine Marktnachricht via AS4 zu versenden, sowie den Prozess über die B2B zu monitoren.
Das Backend (z.B. AEP-Mako-Cloud) übergibt eine Marktnachricht an die B2B (1). Im Rahmen des B2B-Workflows werden Monitoring Information generiert. Am Ende des B2B-Workflows wird die Nachricht an das AS4-System übergeben (2).
Aus Sicht der B2B ist der Prozess erst abgeschlossen, nachdem die Quittung verarbeitet worden ist. Das AS4-System überträgt die Quittung an das B2B-System (3), wo diese zum Monitoring abgespeichert wird.
Im Rahmen des B2B-Monitorings ist ein Neustart von ausgehenden Nachrichten möglich.
Das folgende Diagramm zeigt den Ablauf des AS4-Outbound-Prozesses innerhalb des B2B-Systems im Detail.
Der B2B-Workflow (1) wird durch ein Backend (z.B. AEP-Mako-Cloud) angestoßen. Das Backend übergibt eine Marktnachricht an die B2B. Der B2B-Workflow kann auch durch einen Neustart erneut angestoßen werden.
Im Rahmen des B2B-Workflows wird die Marktnachricht in der SQL-Datenbank der B2B gespeichert (2), z.B. mit Hilfe einer SetPropertyAction. Am Ende des B2B-Workflows wird der B2B-Message-Service über eine REST-Anfrage getriggert (3), hierzu ist der REST-Client-Service zu nutzen.
Der B2B-Message-Service empfängt den REST-Aufruf (3) und erzeugt zunächst nur eine interne AMQP-Nachricht (4).
Der B2B-Message-Service holt die AMQP Nachricht in der zugehörigen Queue ab (5). Er lädt die Marktnachricht aus der SQL-Datenbank (6) und
übermittelt die Daten an das AS4-System über die Exchange as4.outbound.request
(7).
Das AS4-System übermittelt einen Bericht (inklusive Geschäftsnachricht & Quittung falls vorhanden) per AMQP. Der B2B-Message-Service holt
den Bericht über die Queue as4.receipt.outbound.delivery
ab (8). Er speichert den Bericht in der SQL-Datenbank der B2B (9).
Über das Monitoring der B2B kann nun der Status der Marktnachricht, der AS4-Geschäftsnachricht und der AS4-Quittung eingesehen werden.
as4-pathswitch
Der BDEW schreibt vor, dass während des Übergangszeitraums ein Pathswitch zwischen zwei Marktpartnern durchgeführt werden muss, bevor diese via AS4 kommunizieren dürfen.
Das AS4-System informiert die B2B über durchgeführte Pathswitches, sodass die B2B entscheiden kann, ob Nachrichten über das AS4-System oder einen anderen Übertragungsweg versendet werden sollen.
Nachdem ein Pathswitch vollständig verarbeitet wurde, überträgt das AS4 System eine Nachricht an die Exchange as4.pathswitch.delivery
.
Ein Pathswitch ist vollständig verarbeitet, wenn sowohl Request, Confirmation sowie die zugehörigen Quittungen verarbeitet worden sind.
Der B2B-Message-Service holt die Nachricht in der zugehörigen Queue ab (1). Er speichert die Partnerbeziehung des Pathswitch in der
SQL-Datenbank der B2B innerhalb der Extension AS4_RELATIONS
(2).
Im Rahmen des Workflows des B2B-Tomcat kann auf die Extension AS4_RELATIONS
zugegriffen werden, z.B. über dynamische Ausdrücke. So kann
bestimmt werden, ob die Partnerbeziehung bereits auf AS4 umgestellt worden ist und eine Marktnachricht an das AS4-System übertragen werden
muss oder noch nicht.
Passthrough (Generischer AMQP Versand)
Über diesen Prozess kann ein B2B-Message-Attribut via AMQP verschickt werden. Dieses Attribut kann z.B. eine empfangene AMQP Nachricht sein, die unverändert weitergeleitet werden soll. Dieser Workflow beinhaltet keine AS4-spezifische Logik.
Der Passthrough-Prozess ermöglicht es somit, eine AMQP-Nachricht den B2B-Workflow durchlaufen zu lassen und anschließend via AMQP unverändert weiterzuleiten.
Ein Anwendungsfall ergibt sich, wenn die B2B ausschließlich zum Monitoring eingesetzt wird und weder eine Validierung noch eine Konvertierung oder Splitting der Marktnachricht durchgeführt werden soll, und die dahinterliegenden Systeme ebenfalls per AMQP angebunden sind. Wenn die B2B außerdem die Möglichkeit des Neustarts der Nachrichten bieten soll, ist der Passthrough-Prozess zu nutzen.
Der Passthrough ersetzt in diesem Szenario den AS4-Inbound-Prozess. Die entscheidende Abweichung ist hier, dass die Nachrichten vom B2B-System nicht verändert werden.
Das folgende Diagramm zeigt den Ablauf des Passthrough-Prozesses innerhalb des B2B-Systems im Detail.
Der B2B-Message-Service konsumiert die Nachricht aus einer Queue (1).
Der B2B-Message-Service speichert die Nachricht in der SQL-Datenbank der B2B (2). Der B2B-Queue-Service im B2B-Tomcat crawlt die Datenbank (
3) und stößt den B2B-Workflow für die Nachricht an. Am Ende des B2B-Workflows wird der B2B-Message-Service über eine REST-Anfrage getriggert (4), hierzu ist der REST-Client-Service zu nutzen.
Der B2B-Message-Service empfängt den REST-Aufruf (4) und erzeugt zunächst nur eine interne AMQP-Nachricht (5).
Der B2B-Message-Service holt die AMQP Nachricht in der zugehörigen Queue ab (6). Er lädt die Marktnachricht aus der SQL-Datenbank (7) und
übermittelt die Daten per AMQP über die Exchange b2b.json
(8).
Die Konfiguration des Passthrough-Prozesses ist hier dokumentiert.
Bei der Konfiguration muss sichergestellt werden, dass die Original-AMQP-Nachricht in der SQL-Datenbank gespeichert wird. Dies ist hier dokumentiert.
Edifact
Ein Mako-Backend kann via AMQP Edifact Nachrichten in die B2B schicken.
Der B2B-Message-Service empfängt eine Edifact über die Queue b2b.edifact.default
(1). Er speichert die Edifact in der SQL-Datenbank der
B2B (2). Der B2B-Queue-Service im B2B-Tomcat crawlt die Datenbank (3) und stößt den B2B-Workflow für die Edifact an. Dieser kann z.B. in
den AS4-Outbound-Workflow übergehen.
Die Konfiguration des Empfangs über die Queue b2b.edifact.default
ist hier dokumentiert.
Einfache Konfiguration der application.properties
Datenbankanbindung
Der Microservice benötigt Zugriff auf eine SQL Datenbank. Es ist das gleiche Datenbank-Schema zu konfigurieren, welches auch von der B2B genutzt wird. Die Tabellen müssen bereits zuvor angelegt worden sein. Für weitere Details zum Anlegen der Tabellen sei auf die B2B Dokumentation verwiesen.
#=== JDBC Settings ==='
datasource.url=jdbc:postgresql://localhost:5435/b2bbp
datasource.username=postgres
datasource.password=admin
datasource.schema=b2bbp
Falls Oracle genutzt wird, gilt: es muss mindestens Oracle 12.2 eingesetzt werden, ältere Versionen werden nicht unterstützt.
Message Broker Anbindung
Außerdem benötigt der Service die Konfiguration des Message-Brokers AMQP:
rabbitmq.host=localhost
rabbitmq.port=5672
rabbitmq.username=guest
rabbitmq.password=guest
Konfiguration ausgehend an (externes) AS4 System per AMQP
Es gibt eine interne Queue, welche die messageId und attributeId an den internen Consumer weiterleitet.
b2bMessageExchangeName=b2b.message
b2bMessageGroup=default
Routing ist in diesem Fall nicht nötig. Lediglich der Gruppenname (b2bMessageGroup) kann angepasst werden. Diese Konfiguration wird ebenfalls für den internen Consumer angewendet. Nachdem der Consumer die messageId und die attributeId empfängt, wird die Edifact aus der Datenbank geladen. Danach wird diese an den Message Broker weitergeleitet:
outboundRequestExchangeName=as4.outbound.request
outboundRequestHeaderName=partner
outboundRequestHeaderValues=
Die Variable outboundRequestExchangeName definiert die ausgehende Warteschlange zum Übersetzungsdienst. Wenn Sie die Routing-Option verwenden möchten, bei der Nachrichten basierend auf spezifischen Informationen an verschiedene Warteschlangen gesendet werden, können die Eigenschaften outboundRequestHeaderName und outboundRequestHeaderValues konfiguriert werden. outboundRequestHeaderName kann als Filterkategorie betrachtet werden, während outboundRequestHeaderValues die Werte sind, nach denen die Nachrichten gefiltert werden.
Folgende Parameter werden für outboundRequestHeaderName unterstützt: partner, tenant. Es ist möglich, mehrere Werte durch Kommas getrennt in outboundRequestHeaderValues anzugeben.
Für jeden Wert, der nicht in outboundRequestHeaderValues festgelegt ist, wird automatisch eine Standard-Queue mit der Gruppe default erstellt.
Soll für die Erstellung des AS4 Headers zudem nicht die Codevergabestelle aus der EDIFACT Nachricht verwendet werden (z.B. weil diese falsch ist), sondern aus der ILN geschlossen werden (99er Nummer -> BDEW, 98er Nummer -> DVGW, sonst -> ebCore PartyId-Type), so kann die folgende Property gesetzt werden.
useEdifactRegistrarCodeForAs4=false (default: true, empfohlen: false)
Wird die Property gesetzt so können auch EDIFACT Nachrichten mit falscher Codevergabestelle per AS4 erstellt und potentiell erfolgreich versendet werden.
Empfang von ausgehenden AS4 Nachrichten und Receipts in der B2B
Ausgehende AS4 Nachrichten werden über die folgende Standard-Konfiguration zurück an die B2B des Mandanten übermittelt.
outboundAs4ReceiptExchangeName=as4.receipt.outbound
outboundAs4ReceiptGroup=delivery
outboundAs4ReceiptRoutingKey=https://www.bdew.de/as4/communication/services/MP,https://www.bdew.de/as4/communication/services/FP
outboundAs4ReceiptExchangeType=topic
outboundAs4ReceiptMaxConcurrency=50
spring.cloud.stream.bindings.outboundAs4ReceiptConsumer-in-0.destination=${outboundAs4ReceiptExchangeName}
spring.cloud.stream.bindings.outboundAs4ReceiptConsumer-in-0.group=${outboundAs4ReceiptGroup}
spring.cloud.stream.rabbit.bindings.outboundAs4ReceiptConsumer-in-0.consumer.bindingRoutingKey=${outboundAs4ReceiptRoutingKey}
spring.cloud.stream.rabbit.bindings.outboundAs4ReceiptConsumer-in-0.consumer.exchange-type=${outboundAs4ReceiptExchangeType}
spring.cloud.stream.rabbit.bindings.outboundAs4ReceiptConsumer-in-0.consumer.autoBindDlq=true
spring.cloud.stream.rabbit.bindings.outboundAs4ReceiptConsumer-in-0.consumer.dlq-quorum.enabled=true
spring.cloud.stream.rabbit.bindings.outboundAs4ReceiptConsumer-in-0.consumer.quorum.enabled=true
spring.cloud.stream.rabbit.bindings.outboundAs4ReceiptConsumer-in-0.consumer.max-concurrency=${outboundAs4ReceiptMaxConcurrency}
Dabei wird jede versendete AS4 Nachricht (samt Receipt und Metadaten) über die mitgegebene B2B MessageId der ausgehende B2B zugeordnet und gespeichert.
Die übergebene B2B MessageId kann dabei von “externen” Systemen durch eine Nachrichten Id des externen System wie folgt erweitert werden:
<B2B MessageId>_<external Id>
.
Standardmäßig wird somit zur Zuordnung der B2B Nachricht immer nur der Teil der B2B MessageId verwendet.
Soll die AS4 Nachricht stattdessen an durch den B2B Message Service an ein externes System (z.B. auch ein zweites B2B System) übertragen und
über die <<external Id>
zugeordnet werden, so kann die folgende Property eingestellt werden.
useExternalIdForB2bMessageCorrelation=true (Default: false)
Setzen des Bearbeitungsstatus CTW (CONTRL Waiting) direkt durch den B2B-Message-Service
In der Standardkonfiguration setzt der RestClientService bei AS4-Nachrichten den Bestätigungsstatus auf CTW
, wenn die
MessageContext-Variable B3P_SET_CONTRL_STATE
auf true
gesetzt ist und die Nachricht erfolgreich an das AS4-System übergeben wurde. Falls
nun ein negatives Receipt empfangen wird, wird der Status vom B2B-Message-Service mit MER
überschrieben. Sollte dieses Receipt nicht
ankommen, bleibt der Bestätigungsstatus auf CTW
, obwohl der Versand noch nicht abgeschlossen ist. Dies kann zu unberechtigtem Versand von
Nachforderungsmails führen, da dafür Nachrichten mit Bestätigungsstatus CTW
beachtet werden.
Wird die Property setEdifactAcknowledgementWaiting
in der B2B-Message-Service-Konfiguration auf true
und B3P_SET_CONTRL_STATE
in der
B2B-Konfiguration, bzw im MessageContext auf false
gesetzt, wird der Bestätigungsstatus CTW
vom B2B-Message-Service und erst beim Erhalt
eines positiven Receipts gesetzt. Für weitere Informationen zu B3P_SET_CONTRL_STATE
siehe Anmerkung in der
Konfiguration des RestClientService für AS4-Versand.
Zu beachten:
Der so gesetzte Bestätigungsstatus wird nicht nach CCM und StatusSync kommuniziert. Das beeinträchtigt die Funktionalität des
CCM-Nachforderungsmailjobs. Dieser wird in Kombination mit dem Setzen des Bearbeitungsstatus durch den B2B-Message-Service nicht richtig
funktionieren, da die Nachrichten im CCM-Index nicht auf CTW
gesetzt werden. Stattdessen können der ContrlDeadlineJob und
ContrlDeadlineReminderJob
genutzt werden, da diese nicht auf den CCM-Index zurückgreifen.
Des Weiteren wird die Bearbeitungsstatusänderung nicht in der Status-History auftauchen, ähnlich wie bei anderen Änderungen an Versand- und Bearbeitungsstatus durch den B2B-Message-Service.
Konfiguration eingehender AS4 EDIFACT Nachricht per AMQP
Der Exchange Name, sowie die Gruppe, muss konfiguriert werden. Der vollständige Name der Queue setzt sich demnach wie folgt zusammen: _ _{inboundEdifactExchangeName}.{inboundEdifactGroup}__ . Nachfolgend sind die standardmäßig erforderlichen Konfigurationen aufgeführt.
inboundEdifactExchangeName=as4.inbound
inboundEdifactGroup=delivery
inboundEdifactRoutingKey=http://docs.oasis-open.org/ebxml-msg/ebms/v3.0/ns/core/200704/service
inboundEdifactExchangeType=topic
inboundEdifactChannel=INBOUND_MESSAGES
inboundEdifactErrorChannel=AS4_ERROR
delayedInboundMessagesChannel=IN_DELAYED
Die Variable inboundEdifactChannel bezieht sich auf den B2B-Eingangskanal. B2B-Tomcat kann die Nachricht verarbeiten und der Benutzer kann die Edifact-Nachricht in der MessageMonitor-Ansicht sehen. Zusätzlich dazu werden AS4-Nachricht, AS4-Nachrichtendaten (zusätzliche Informationen zur Geschäftsnachricht), AS4-Empfangsbestätigung, AS4-Empfangsbestätigungsdaten (zusätzliche Informationen zur Empfangsbestätigung) und AS4-Custom-Daten (alle anderen Informationen, die über AMQP gesendet werden) in der Tabelle b2bbp_data_attribute mit den Attributen AS4_MESSAGE, AS4_MESSAGE_DATA, AS4_RECEIPT, AS4_RECEIPT_DATA & AS4_CUSTOM gespeichert. Bei einem Fehler wird die Nachricht an die DLQ (Dead Letter Queue) gesendet.
Zusätzlich dazu wird der BS (Bestätigungsstatus) basierend auf dem Empfangsstatus in der Datenbank gespeichert. Wenn die Empfangsbestätigung nicht zugestellt wurde (Empfangsbestätigung oder zugestellte Empfangsbestätigung ist leer), wird kein BS gespeichert. Wenn der Empfangsstatus leer ist (positive Empfangsbestätigung), wird der BS ‘MSU’ gespeichert. Wenn der Empfangsstatus ausgefüllt ist ( negative Empfangsbestätigung), wird der BS ‘MSE’ gespeichert. Wenn die Empfangsbestätigung nicht zugestellt oder negativ ist, wird der B2B-Kanal inboundEdifactErrorChannel verwendet, um die Nachricht in der Datenbank zu speichern. Andernfalls wird der B2B-Kanal inboundEdifactChannel verwendet. delayedInboundMessagesChannel wird verwendet, wenn die Nachricht verzögert ist. Dies ist möglich, wenn Nachrichten erneut an das Backend geliefert werden, wie im nachfolgenden Absatz erläutert wird.
Als Nachrichten Eingangsdatum (Spalt “Start” im Nachrichten-Monitor) wird im Standard das Eingangsdatum in der B2B gesetzt. Soll die Nachricht hier stattdessen zum Eingangsdatum der AS4 Nachricht gespeichert werden (vergleiche mit der analogen Einstellung für den Mail-Eingang “B3P_SET_ORIG_RECEIVED_DATE”), so kann die folgende Einstellung gesetzt werden.
useAs4ReceivedAsMessageStarted=true (default: false)
Konfiguration ausgehender AEP.API Anfragen in der B2B
Der Versand von API Informationen zum Versand an einen Marktpartner erfolgt über das Standard Outbox-Relay mit einer entsprechenden Konfiguration des B2B Workflows.
Damit die B2B auch die Versanddaten zur ausgehenden API-Anfrage an die B2B zurückmeldet, ist per Default der Exchange api.client.response und die Queue api.client.response.dafault mit entsprechendem Bindung wie folgt konfiguriert.
outboundApiRequestProcessingDataExchangeName=api.client.response
outboundApiRequestProcessingDataQueueName=b2b.api.client
outboundApiRequestProcessingDataQueueGroup=default
spring.cloud.stream.bindings.outboundApiRequestProcessingDataConsumer-in-0.destination=${outboundApiRequestProcessingDataQueueName}
spring.cloud.stream.bindings.outboundApiRequestProcessingDataConsumer-in-0.group=${outboundApiRequestProcessingDataQueueGroup}
spring.cloud.stream.rabbit.bindings.outboundApiRequestProcessingDataConsumer-in-0.consumer.autoBindDlq=true
spring.cloud.stream.rabbit.bindings.outboundApiRequestProcessingDataConsumer-in-0.consumer.dlq-quorum.enabled=true
spring.cloud.stream.rabbit.bindings.outboundApiRequestProcessingDataConsumer-in-0.consumer.quorum.enabled=true
spring.cloud.stream.rabbit.bindings.outboundApiRequestProcessingDataConsumer-in-0.consumer.max-concurrency=50
spring.cloud.stream.rabbit.bindings.outboundApiRequestProcessingDataConsumer-in-0.consumer.declareExchange=false
spring.cloud.stream.rabbit.bindings.outboundApiRequestProcessingDataConsumer-in-0.consumer.bind-queue=false
Aus dieser Queue consumiert der b2b-message-service die Verarbeitungsdaten ausgehender API-Anfragen, aktualisiert die Status der zugehörigen B2B Nachricht und speichert die Verarbeitungsdaten ab.
Konfiguration eingehender AEP.API Anfragen in der B2B
Der B2B Message Service verfügt nun im Standard über die folgende Konfiguration eingehende API-Requests des AEP.API Systems über eine AMQP Queue zu empfangen. Aus jeder empfangenen API-Anfrage wird dann eine B2B Nachricht erstellt und dem B2B Workflow übergeben.
inboundApiRequestProcessingDataExchangeName=api.server.response
inboundApiRequestProcessingDataQueueName=b2b.api.server
inboundApiRequestProcessingDataQueueGroup=default
spring.cloud.stream.bindings.inboundApiRequestProcessingDataConsumer-in-0.destination=${inboundApiRequestProcessingDataQueueName}
spring.cloud.stream.bindings.inboundApiRequestProcessingDataConsumer-in-0.group=${inboundApiRequestProcessingDataQueueGroup}
spring.cloud.stream.rabbit.bindings.inboundApiRequestProcessingDataConsumer-in-0.consumer.autoBindDlq=true
spring.cloud.stream.rabbit.bindings.inboundApiRequestProcessingDataConsumer-in-0.consumer.dlq-quorum.enabled=true
spring.cloud.stream.rabbit.bindings.inboundApiRequestProcessingDataConsumer-in-0.consumer.quorum.enabled=true
spring.cloud.stream.rabbit.bindings.inboundApiRequestProcessingDataConsumer-in-0.consumer.max-concurrency=50
# The properties below are needed to disable default behavior of creating an exchange name for the queue name as we are binding api.server.response -> b2b.api.server.default
spring.cloud.stream.rabbit.bindings.inboundApiRequestProcessingDataConsumer-in-0.consumer.declareExchange=false
spring.cloud.stream.rabbit.bindings.inboundApiRequestProcessingDataConsumer-in-0.consumer.bind-queue=false
inboundApiRequestChannel=IN_ERR
inboundApiRequestErrorChannel=IN_API-REQUEST_ERROR
Für die erstellte B2B Nachricht können zwei Channel konfiguriert werden, je nachdem ob der übermittelte API-Request
a) erfolgreich dem Marktpartner bestätigt werden konnte: inboundApiRequestChannel (Default: IN_ERR)
b) mit einem Fehlercode abgelehnt oder nicht bestätigt werden konnte: inboundApiRequestErrorChannel (Default: IN_API-REQUEST_ERROR)
Erneute Verarbeitung von AS4-Nachrichten
Um Nachrichten erneut zu verarbeiten, werden AS4-Nachrichten mithilfe eines Filters aus der Datenbank des AS4-Message-Services abgerufen und dann erneut an die entsprechenden Services übermittelt. Der B2B-Message-Service filtert Duplikate heraus und bietet die Möglichkeit, Nachrichten als ’ verspätet’ zu kennzeichnen. Es kann spezifiziert werden, ab wann Nachrichten als verspätet betrachtet werden sollen:
delayIntervalHours=72
Demnach werden alle Nachrichten als verspätet gekennzeichnet, die älter als 72 (delayIntervalHours) Stunden sind.
Eine Duplikatserkennung der erneut verarbeiteten Nachrichten wird immer durchgeführt. Diese Funktion kann jedoch standardmäßig durch eine Eigenschaft aktiviert sein:
duplicateDetection=true
Der Default dieser Eigenschaft ist true.
Verspätete Nachrichten werden in einen eigenen Channel geroutet, vgl. hierzu Property delayedInboundMessagesChannel
(default
IN_DELAYED
).
Mehr Infos zu der erneuten Verarbeitung von AS4-Nachrichten gibt es in der folgenden Dokumentation: AS4-Redelivery
Speicherung des gesamten Queue-Objekts und Weiterleitung über die B2B einen anderen Service
Der B2B Message Service kann das gesamte Input-Json-Objekt in der Datenbank speichern. Es ist standardmäßig deaktiviert, da es für die Standard-AS4-Einrichtung nicht benötigt wird und kann über die Eigenschaft saveInputMessage aktiviert werden. Das Objekt wird in dem Attribut “INPUT_MESSAGE” gespeichert.
saveInputMessage=true
Der B2B Message Service kann Queue-Objekte über die B2B weitergeben. Zunächst muss die Eingangsnachricht bzw. das Eingangsobjekt wie im vorherigen Abschnitt in der Datenbank gespeichert werden.
Der REST-Endpunkt /messages ist auch für den Empfang der messageId, attributeId und des Workflows (der Workflow muss json sein) verantwortlich und wird verwendet, um das gesamte eingehenden json-Objekt aus der B2B-Datenbank abzurufen (attributeId=INPUT_MESSAGE). Um dies zu erreichen, gibt es eine interne Queue, welche die messageId, attributeId und den Workflow an den internen Consumer weiterleitet.
b2bMessageExchangeName=b2b.message
b2bMessageGroup=default
Anschließend wird das json-Objekt aus der Datenbank abgerufen und zur weiteren Verarbeitung an eine andere Queue gesendet.
b2bInboundPassThroughExchangeName=b2b.json
b2bInboundPassThroughExchangeType=topic
Um die Nachricht auf der Grundlage der Informationen des json-Objekts weiterzuleiten, können der Routingkey und der Headername konfiguriert werden.
b2bInboundPassThroughHeaderNames=tenant
b2bInboundPassThroughRoutingKeyExpression=headers.tenant
b2bInboundPassThroughExchangeType=topic
In diesem Beispiel wird die Nachricht auf der Grundlage des Tenant-Wertes des json-Objekts weitergeleitet. Es ist auch möglich, die Weiterleitung auf der Grundlage verschiedener Routingkeys vorzunehmen, indem mehrere durch Komma getrennte headerNames konfiguriert werden.
b2bInboundPassThroughHeaderNames=tenant,partner
b2bInboundPassThroughRoutingKeyExpression=headers.tenant + '.' + headers.partner
b2bInboundPassThroughExchangeType=topic
Wichtig ist, dass der Exchange, die Queues und die entsprechenden Bindings für den Passtrough Workflow vor dem Start des B2B Message Service erstellt werden müssen, da es sonst sein kann, dass Nachrichten verloren gehen. Eine entsprechende Dokumentation zum Anlegen der Queues ist hier dokumentiert.
Erneute Verarbeitung von AS4-Nachrichten
Um Nachrichten erneut zu verarbeiten, werden AS4-Nachrichten mithilfe eines Filters aus der Datenbank des AS4-Message-Services abgerufen und dann erneut an die entsprechenden Services übermittelt. Der B2B-Message-Service filtert Duplikate heraus und bietet die Möglichkeit, Nachrichten als ’ verspätet’ zu kennzeichnen. Es kann spezifiziert werden, ab wann Nachrichten als verspätet betrachtet werden sollen:
delayIntervalHours=72
Demnach werden alle Nachrichten als verspätet gekennzeichnet, die älter als 72 (delayIntervalHours) Stunden sind. Mehr Infos gibt es in der folgenden Dokumentation: AS4-Redelivery
Konfiguration Pathswitch per AMQP
Der Service empfängt per AMQP einen Pathswitch vom AS4-System und speicher ihn in der Extension ‘AS4_RELATIONS’ in der B2B-Datenbank. Der
Name des Exchanges muss konfiguriert werden. Die Gruppe kann ebenfalls konfiguriert werden, so dass der Name der Queue wie folgt
aussieht:
pathswitchExchangeName=as4.pathswitch.delivery
pathswitchGroup=default
pathswitchExchangeType=topic
Die Struktur der Extension sieht wie folgt aus:
<tenant-ILN>.<partner-ILN>.AS4=true/false
<tenant-ILN>.<partner-ILN>.AS4ID=<as4id>
<tenant-ILN>.<partner-ILN>.delivered=<delivered-timestamp>
Mit ‘.AS4’ wird angegeben ob die zwei Marktpartner per AS4 miteinander kommunizieren oder nicht. In der Locktabelle ist anhand eines Locks zu erkennen, ob ein B2B Message Service gerade in diese Extension schreibt.
Konfiguration Edifact über AMQP empfangen
Der B2B-Message-Service kann Edifact Nachrichten per AMQP empfangen und verarbeiten. Hierfür muss eine entsprechende Queue konfiguriert werden. Darüber hinaus kann der BASE_CHANNEL angegeben werden.
b2bEdifactExchangeName=b2b.edifact
b2bEdifactGroup=default
b2bEdifactChannel=OUT_B2B_MSG_SERVICE
Der Queue-Eintrag enthält neben der Nachricht auch die Inbound-/Outbound-Richtung und die MessageId als externe Referenz. Beispiel Nachricht für die Queue:
{
"message": "base64 encoded edifact",
"direction": "inbound/outbound",
"messageId": "M001"
}
Payload zippen
Die Nutzlast/der Anhang im ausgehenden Fluss wird genau dann gezippt, wenn zipPayload=true konfiguriert ist (Standardeinstellung: false).
zipPayload=false
Falls dieses Feature genutzt wird, muss dies mit dem AS4 abgestimmt werden. Falls Sie AEP AS4 nutzen, können Sie die gleiche Property am AS4-Receipt-Service konfigurieren.
Switch Partition
Die Funktion Switch Partition kann durch die folgende Eigenschaft aktiviert oder deaktiviert werden. Der Standardwert ist false.
switchPartition=false
Max Concurrency - Parallelität
Für jeden Consumer ist es möglich die Eigenschaft max-concurrency
zu setzen. Diese definiert die maximale Anzahl von gleichzeitigen
Verarbeitungsthreads, die für einen Consumer gestartet werden können. Der Default steht für jeden Consumer auf 50.
b2bMessageMaxConcurrency=50
inboundEdifactMaxConcurrency=50
pathswitchMaxConcurrency=50
outboundAs4ReceiptMaxConcurrency=50
b2bEdifactMaxConcurrency=50
Zeitzone
Die Server-Zeitzone ist auf die gleiche Zeitzone wie die des B2B-Servers zu stellen. Die Server-Zeitzone darf nachträglich nicht mehr geändert werden.
REST API Dokumentation
Der Service bietet verschiedene REST Schnittstellen an, Details lassen sich der Swagger Dokumentation entnehmen.
Darüber hinaus bietet die API Server-Health Informationen an.
Der Port lässt sich über folgende Property konfigurieren: server.port=8080
Swagger
Die Beschreibung der REST API lässt sich, im Fall einer Docker Installation, unter
http://host.docker.internal:8090/aep-b2b-message-service/swagger-ui/index.html
oder unter
http://localhost:8080/aep-b2b-message-service/swagger-ui/index.html
finden.
Anhang: Gesamtkonfiguration
Profil kann durch die folgende Eigenschaft aktiviert werden
spring.profiles.active=no-keycloak-enriched, postgres
Profilbasierte Datenbankkonfiguration: zum Beispiel: für Postgres-Profil - application-postgres.properties
#=== JDBC Settings ==='
datasource.url=jdbc:postgresql://b2b-database:5432/b2bbp
datasource.username=postgres
datasource.password=
datasource.schema=b2bbp
Profilbasierte Datenbankkonfiguration: zum Beispiel: für MSSQL-Profil - application-mssql.properties
#=== JDBC Settings ==='
datasource.url=jdbc:sqlserver://localhost:2433;DatabaseName=b2bbp;trustServerCertificate=true;
datasource.username=SA
datasource.password=
datasource.schema=dbo
Profilbasierte Datenbankkonfiguration: zum Beispiel: für Oracle-Profil - application-oracle.properties
#=== JDBC Settings ==='
datasource.url=jdbc:oracle:thin:@//localhost:1521/orclb2b
datasource.username=b2bbp
datasource.password=
datasource.schema=b2bbp
Folgende Konfiguration reicht in einem Standard-System aus: application.properties
:
#=== Rabbitmq Configuration ===#
rabbitmq.host=rabbitmq3
rabbitmq.port=5672
rabbitmq.username=guest
rabbitmq.password=${RABBITMQ_PASSWORD}
inboundEdifactRoutingKey=https://www.bdew.de/as4/communication/services/MP
outboundAs4ReceiptRoutingKey=https://www.bdew.de/as4/communication/services/MP
Allgemeine Hinweise zur Konfiguration finden Sie hier.
Konfiguration für ServiceBus-Anbindung in der AEP
Die Konfiguration für den Azure ServiceBus kann komplett über Umgebungsvariablen in der docker-compose.yml erfolgen.
Für die Anbindung an den ServiceBus muss zunächst das Profil “servicebus” aktiviert werden.
Alle Queues, die vom B2B-Message-Service verwendet werden, sind Mandanten-scharf abgesichert. Deshalb erhalten die entsprechenden Exchange-Names ein Mandanten-Postfix. Ebenso gibt es für jede Queue einen Mandanten-scharfen ConnectionString.
Die vollständige Konfiguration kann folgendermaßen aussehen:
b2b-message-service:
image: ${NEXUS_ERP}/b2b/b2b-message-service:${VERSION_B2B_MESSAGE_SERVICE}
container_name: b2b-message-service
environment:
TZ: ${TIME_ZONE}
SPRING_PROFILES_ACTIVE: servicebus, no-keycloak-enriched
SPRING_CLOUD_AZURE_SERVICEBUS_NAMESPACE: ${SERVICEBUS_NAMESPACE}
OUTBOUNDAS4RECEIPTEXCHANGENAME: as4.receipt.outbound.${AS4_TENANT}
INBOUNDEDIFACTEXCHANGENAME: as4.inbound.${AS4_TENANT}
PATHSWITCHEXCHANGENAME: as4.pathswitch.delivery.${AS4_TENANT}
B2BMESSAGEEXCHANGENAME: b2b.message.${AS4_TENANT}
SPRING_CLOUD_STREAM_BINDERS_SBB2BMESSAGE_TYPE: servicebus
SPRING_CLOUD_STREAM_BINDERS_SBAS4RECEIPTOUTBOUND_TYPE: servicebus
SPRING_CLOUD_STREAM_BINDERS_SBAS4INBOUND_TYPE: servicebus
SPRING_CLOUD_STREAM_BINDERS_SBAS4PATHSWITCHDELIVERY_TYPE: servicebus
SPRING_CLOUD_STREAM_BINDERS_SBAS4OUTBOUNDREQUEST_TYPE: servicebus
SPRING_CLOUD_STREAM_BINDINGS_B2BMESSAGEEVENTCONSUMERIN0_BINDER: sbb2bmessage
SPRING_CLOUD_STREAM_BINDINGS_PRODUCEB2BMESSAGEIDOUT0_BINDER: sbb2bmessage
SPRING_CLOUD_STREAM_BINDINGS_OUTBOUNDAS4RECEIPTCONSUMERIN0_BINDER: sbas4receiptoutbound
SPRING_CLOUD_STREAM_BINDINGS_RECEIVEDAS4MESSAGECONSUMERIN0_BINDER: sbas4inbound
SPRING_CLOUD_STREAM_BINDINGS_PATHSWITCHCONSUMERIN0_BINDER: sbas4pathswitchdelivery
SPRING_CLOUD_STREAM_BINDINGS_OUTBOUNDREQUESTOUT0_BINDER: sbas4outboundrequest
SPRING_CLOUD_AZURE_SERVICEBUS_CONNECTIONSTRING: ''
SPRING_CLOUD_STREAM_BINDERS_SBB2BMESSAGE_ENVIRONMENT_SPRING_CLOUD_AZURE_SERVICEBUS_CONNECTIONSTRING: ${SERVICEBUS_CONNECTIONSTRING_B2BMESSAGE}
SPRING_CLOUD_STREAM_BINDERS_SBAS4RECEIPTOUTBOUND_ENVIRONMENT_SPRING_CLOUD_AZURE_SERVICEBUS_CONNECTIONSTRING: ${SERVICEBUS_CONNECTIONSTRING_AS4RECEIPTOUTBOUND}
SPRING_CLOUD_STREAM_BINDERS_SBAS4INBOUND_ENVIRONMENT_SPRING_CLOUD_AZURE_SERVICEBUS_CONNECTIONSTRING: ${SERVICEBUS_CONNECTIONSTRING_AS4INBOUND}
SPRING_CLOUD_STREAM_BINDERS_SBAS4PATHSWITCHDELIVERY_ENVIRONMENT_SPRING_CLOUD_AZURE_SERVICEBUS_CONNECTIONSTRING: ${SERVICEBUS_CONNECTIONSTRING_AS4PATHSWITCH}
SPRING_CLOUD_STREAM_BINDERS_SBAS4OUTBOUNDREQUEST_ENVIRONMENT_SPRING_CLOUD_AZURE_SERVICEBUS_CONNECTIONSTRING: ${SERVICEBUS_CONNECTIONSTRING_AS4OUTBOUNDREQUEST}
SPRING_CLOUD_FUNCTION_DEFINITION: b2bMessageEventConsumer;receivedAs4MessageConsumer;pathswitchConsumer;outboundAs4ReceiptConsumer
DATASOURCE_URL: jdbc:postgresql://b2b-database:5432/b2bbp
DATASOURCE_USERNAME: postgres
DATASOURCE_SCHEMA: b2bbp
DATASOURCE_PASSWORD: ${B2B_DATABASE_PASSWORD}
labels:
- "traefik.enable=true"
- "traefik.http.routers.b2b-message-service.rule=Host(`${HOST}`) && PathPrefix(`/aep-b2b-message-service`)"
Konfiguration B2b Queue
Aufteilung nach Nachrichtengrößen
Nachrichten werden aufgrund ihrer Größe in 4 Gruppen eingeteilt: SMALL, MEDIUM, LARGE und EXCLUSIVE. Die Grenzen werden mithilfe der Eigenschaft b2bQueueMessageSizes definiert.
Beispiel:
b2bQueueMessageSizes.medium=100000
b2bQueueMessageSizes.large=1000000
b2bQueueMessageSizes.exclusive=5000000
Nachrichten mit 1-99.999 Bytes sind SMALL, Nachrichten mit 100.000-999.999 Bytes sind MEDIUM, Nachrichten mit 1.000.000-4.999.999 Bytes sind LARGE und Nachrichten mit 5.000.000 und mehr Bytes sind EXCLUSIVE. Default:
b2bQueueMessageSizes.medium=10000
b2bQueueMessageSizes.large=500000
b2bQueueMessageSizes.exclusive=2500000
Sie können nicht 0 angeben, sonst wird der Standardwert verwendet.
Priorisierung der Nachrichten bei der Queue-Abarbeitung
Nachrichten im B2B können unterschiedliche Prioritäten haben. Die Prioritäten sind wie folgt: ultra, high, medium, low, very_low Die Priorität kann als Prioritätsklasse oder Dokumenttyp konfiguriert werden. Beachten Sie, dass die dokumenttypbasierte Konfiguration veraltet ist. Die Standardpriorität ist für alle Nachrichtentypen niedrig.
Beispiel einer Konfiguration nach Prioritätsklasse in application.yml:
b2b-queue-priority:
priority-classes:
- service-id: "https://www.bdew.de/as4/communication/services/FP"
level: ultra
- type: CONTRL
level: high
- type: UTILMD
level: high
- service-id: "https://www.bdew.de/as4/communication/services/MP"
level: medium
default-priority: low
Beispiel einer Konfiguration nach Dokumenttyp:
b2bQueuePriority.defaultPriority=ultra
b2bQueuePriority.bdewDocumentTypes[0].type=CONTRL
b2bQueuePriority.bdewDocumentTypes[0].level=ultra
b2bQueuePriority.bdewDocumentTypes[1].type=UTILMD
b2bQueuePriority.bdewDocumentTypes[1].level=low
oder alternativ application.yml
b2bQueuePriority:
defaultPriority: ultra
bdewDocumentTypes:
- type: CONTRL
level: ultra
- type: UTILMD
level: low
Outbox Relay
Die B2B-Outbox besteht aus 2 Komponenten: der OutboxAction (im B2B Channel) und dem Outbox-Relay (im B2B-Message-Service). Dieser Abschnitt dokumentiert das Outbox-Relay.
Die Outbox Relay-Komponente ist darauf ausgelegt, eine zuverlässige Nachrichtenübermittlung von der Tabelle B2BBP_OUTBOX innerhalb der B2B-Datenbank an einen Message Broker zu ermöglichen. Dieser Prozess stellt sicher, dass Nachrichten effizient verarbeitet und weitergeleitet werden, wobei die angegebenen Konfigurationseigenschaften eingehalten werden.
Konfigurationseigenschaften
Eigenschaft | Standardwert | Beschreibung |
---|---|---|
outbox.outbox-relay | false | Aktiviert oder deaktiviert das Relay. |
outbox.outbox-exchange | b2b.outbox | Legt den Exchange-Namen für den Message Broker fest. |
outbox.outbox-exchange-type | topic | Definiert den Typ des Exchange (z. B. topic, direct, etc.). |
outbox.outbox-relay-pause-ms | 2000 | Legt die Pausendauer (in Millisekunden) fest, wenn das Relay keine Einträge abruft. |
outbox.outbox-fetch-size | 50 | Bestimmt die Anzahl der Outbox-Einträge, die in jedem Aufruf abgerufen werden sollen. |
Verwendungsbeispiel
Um die Outbox Pattern-Komponente mit den angegebenen Eigenschaften zu verwenden, stellen Sie sicher, dass Ihre Konfigurationsdatei die folgenden Einträge enthält:
outbox.outbox-relay=true
outbox.outbox-exchange=b2b.outbox
outbox.outbox-exchange-type=topic
outbox.outbox-relay-pause-ms=2000
outbox.outbox-fetch-size=50
Diese Konfiguration ermöglicht es der Komponente, jeweils 50 Einträge aus der Tabelle b2bbp.outbox abzurufen, Nachrichten zu erstellen und sie an den b2b.outbox Exchange vom Typ topic weiterzuleiten, mit einer Pause von 2 Sekunden zwischen jeder Relay-Operation.
B2B Inbox
Eine Nachricht kann direkt per AMQP an die B2B übergeben werden, ohne dabei eine spezifische API einhalten zu müssen. Sie ist dafür einfach als Payload der AMQP-Nachricht zu übermitteln, z.B. eine Fahrplan-XML als AMQP Payload.
Um dieses Feature zu nutzen, muss der Consumer am B2B-Message-Service konfiguriert werden. Weiterhin muss ein Base-Service angegeben werden. Dieser muss im B2B-Customizing gepflegt sein.
b2b-inbox:
enabled: true
base-service: B2B-AMQP-Inbox-Service
B2B Outbound Error Channel
Der B2B Message Service verschiebt eine ausgehende AS4-Nachricht in der B2B in einen konfigurierbaren Channel, wenn ein negativer Status vorliegt (neg. VS, neg. BS). Dieser Channel kann wie folgt im B2B Message Service konfiguriert werden.
outbound-error-channel=AS4_OUTBOUND_ERROR
Wichtig ist zu beachten, dass dieser Channel auch in der B2B konfiguriert und mit Actions gefüllt werden sollte. Zum Beispiel mit der AS4ErrorMailAction.
Anhang
Referenz zu den Originaldiagrammen (intern)
View Me Edit Me