Der edi-json.converter Service bietet die Möglichkeit Edifact Nachrichten in ein fachliches JSON der Nachricht zu konvertieren, welches zur Datenübermittlung an ein entsprechendes fachliches Backendsystem geeignet ist.

Hintergrund

Zur Marktkommunikation im regulierten Energiemarkt sind (durch die Spezifikationen des BDEW/DVGW) EDIFACT Nachrichten vorgegeben. Da das EDIFACT Datenformat zur technischen Verarbeitung wenig geeignet ist, definiert üblicherweise ein Backend-System zur Verarbeitung der fachlichen Prozesse (wie z.B. ISU, SXP, MBS) ein anderes Datenformat. Eine Hauptaufgabe der technischen Marktkommunikation (wie der B2B) ist es somit das Mapping der Nachrichten (in beiden Richtungen) zwischen EDIFACT und dem Datenformat des zugehörigen Backends (je nach fachlichem Prozess) herzustellen. Im Zuge dessen wurde das “edi-json” entwickelt, eine JSON Repräsentation/Library der EDIFACT, welches als Datenformat von (künftigen) Backend-Systemen von Arvato verwendet wird, z.B. SXP, AEP Mako Cloud, PKS.

Technisch wird die Konvertierung durch eine eigenständige Applikation realisiert, die das Nachrichten-Mapping per REST durch einen (Micro-)Service anbietet, der von allen Systemen verwendet werden kann.

Aufbau

Der Microservice ist eine eigenständige SpringBoot Applikation, die einen Post Endpunkt pro Konvertierungrichtung anbietet. Streng genommen wäre hier die GET Methode angebrachter, diese übermittelt ihre Daten aber nicht im Request Body, der bei einer Größe von potentiell mehreren Megabytes die bessere Option darstellt. Alternativ wäre eine Datenübermittlung im Rahmen eines File Uploads. Dieser Weg wurde aber hier nicht gewählt.

Unterstützte Formate und Sprache

Ab der Formatumstellung im Oktober 2022 wird das edi-json Mapping von allen EDIFACT Formatversionen des deutschen Strommarktes (definiert durch den BDEW) unterstützt. Die edi-json Datenstruktur liegt dabei ab den Formatversionen zur Umstellung Oktober 2022 in deutscher Sprache vor. Die Benennungen der Felder erfolgen dabei direkt anhand der Spezifikationen des BDEWs aus dem MIG Dokumenten, sodass die edi-json hiermit fachlich leicht lesbar werden.

Für EDIFACT Formatversionen vor der Formatumstellung im Oktober 2022 wird nur das Mapping ausgewählter wichtiger Formate unterstützt, nämlich: UTILMD, MSCONS, ORDERS, ORDRSP, IFTSTA, APERAK. Zudem liegt hier das edi-json in der Regel nur in englischer Sprache vor.

Sollte das edi-json Mapping auch von Gas oder anderen EDIFACT Formaten benötigt werden, so kann dies beauftragt werden.

Datenverarbeitung

Die übermittelten Daten werden synchron konvertiert und die Resultate im Responsebody übertragen.

Konfiguration des Microservice

Der Microservice wird über die Datei application.yml konfiguriert. Relevante Settings dabei

  • server.port - Der Port unter den der Service erreichbar sein soll
  • andere aus SpringBoot bekannte parameter wie logging etc.

Versionsinfo

Die aktuelle Version des Microservice kann mit Hilfe des Endpunkts /actuator/info abgerufen werden.

Release Download

Der edi-json.converter kann als Docker Image docker-nob-erp.next-level-apps.com/edi-json.converter:${EDIC_VER} bezogen werden oder über das PrivateDL (mit berechtigtem Zugang) als Artefakt heruntergeladen werden.

Release Prozess

Mindestens zu jeder neuen Formatumstellung oder bei korrigierten Lesefassungen (mit für das Mapping relevanten Änderungen auf unterstützten Formatversionen) wird ein neues Release von uns bereit gestellt (analog zum Validation Content (VC)). Ansonsten gibt es keinen regulären Release Prozess.

Ein edi-json.converter Release ist i.A. unabhängig von anderen Releases (z.B. B2B oder VC).

Die Release Notes zum edi-json.converter finden sich im hier.

Deployment

Docker Container

Beispiel Eintrag in docker-compose.yml zum Start einer edi-json.converter Instanz.

services:
  edic01:
    image: docker-nob-erp.next-level-apps.com/edi-json.converter:${EDIC_VER}
    hostname: edic01
    container_name: edic01
    restart: always
    command: "-Xmx4g"
    ports:
      - "8090:8080"
      # management server port
      - "9001:9001"
      # debug
#      - "5005:5005"
    environment:
      - TZ=Europe/Berlin
      - JAVA_OPTS= -XX:+ExitOnOutOfMemoryError
      # debug
#      - JAVA_TOOL_OPTIONS=-agentlib:jdwp=transport=dt_socket,address=5005,server=y,suspend=n
    volumes:
      - ./logs_container:/logs
      - /etc/localtime:/etc/localtime:ro

Start ohne Docker

Das Artefakt des edi-json.converters kann einfach mit dem Befehl

java --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED -jar edi-json.converter.jar

im Verzeichnis des Artefakts ausgeführt werden.

Hinweis: Der edi-json.converter läuft mit Java 17, welches hierbei verwendet werden muss.

Der ausgeführte Service (zum Beispiel sein Port via server.port) kann dabei durch ein application.yml File, welches neben der jar gelegt wird, konfiguriert werden. Die Default Einstellungen aus dem Artefakt sehen wie folgt aus:

server:
  port: 8080

logging:
  level:
    root: INFO
    com.nextlevel.edi.json.converter: INFO

spring:
  main:
    allow-bean-definition-overriding: true

management:
  server:
    port: 9001
  endpoint:
    info:
      enabled: true
    health:
      show-details: always

Verwendung zusammen mit der B2B

Schnell-Customizing

Es folgt ein minimales Customizing. Dieses stellt die Edi-Json Grundfunktionalitäten zur Verfügung, die in den folgenden Abschnitten genauer erläutert werden.

globalProperties:
  EDIJSON_CONVERTER_URL: "http://edi-json-converter:8080"

services:
  "ProcessTrigger":
    name: EdiJsonMeta an ProcessTrigger
    class: com.nextlevel.services.outbound.http.ProcessTriggerService
    type: REST
    direction: OUT
    properties:
      URL: "http://sxp-processtrigger-sim:8080"
      MONITOR_OUTPUT: true
  "EdiJsonInbound":
    name: EdiJson Receiver
    type: REST
    channel: OUT_SEP
    direction: IN

actions:
  "SXP-ProcessTrigger #730":
    id: 730
    class: org.b2bbp.runtime.actions.internal.SetPropertyAction
    description: 'Ruft den Service auf, der das EdiJson-Meta an den SXP-ProcessTrigger übergibt.'
    properties:
      B3P_USED_SERVICE_ID:
        value: "ProcessTrigger"
        techMon: true
  "EdiJson-2-Edifact #731":
    id: 731
    class: com.nextlevel.edifactjson.mapping.EdiJson2EdifactMappingAction
    description: 'Action, die das EdiJson in eine Edifact konvertiert.'
    properties:
      URL:
        value: "http://edi-json-converter:8080"
        techMon: true

channels:
  -
    id: IN_SXP
    direction: IN
    actions:
      "ValidatorAction": true
      "Contrl erzeugen": true
      "Aperak erzeugen": true
      "Übergabe an SXP-ProcessTrigger #730": true
      "ErrorMailHandler": false
  -
    id: OUT_SXP
    direction: OUT
    actions:
      "EdiJson-2-Edifact #731": true
      "IndexingService Volltext": true
      "Msg versenden (Mail/AS2)": true
      "ErrorMailHandler": false

Einleitung

Die folgenden zwei Schaubilder zeigen schematisch wie der edi-json.converter Microservice zusammen mit der B2B und einem angeschlossenen Backend (z.B. der SXP Process Engine) konfiguriert werden kann, welches über edi-json (mit der B2B) kommuniziert. Dabei sind die folgenden zwei Kommunikationsrichtungen zu beachten:

Markt -> Backend (Edifact -> JSON)

SXP-Inbound

Innerhalb der B2B findet zunächst eine normale Nachrichtenverarbeitung statt. Hier findet keine Push-Kommunikation statt. Es wird nur ein GET Endpoint angeboten, der es erlaubt über die MessageId einer verabeiteten Nachricht diese im JSON-Format abzurufen.

Eine Push-Kommunikation kann jedoch separat über den ProcessTrigger realisiert werden: Am Ende der Verarbeitung wird der ProcessTriggerService im Channel aufgerufen, welches ein MetaDaten-JSON ans Backend-System sendet. Dieses enthält u.a. die MessageId.

Nach Abschluss der Verarbeitung kann die JSON-Representation der verarbeiteten Edifact über den folgenden B2B REST Endpoint (tatsächliche Adresse über Swagger einsehbar) erhalten werden.

GET [b2b]/api/edifactjson/v1/edifact/{messageid}

Dabei wird zunächst die Ursprungsnachricht anhand der messageId aus der Datenbank geladen. Wurden einige Vorgänge der Nachricht per APERAK abgelehnt, so wird nur die “gekürzte” EDIFACT der APERAK-validen Vorgänge geladen. Ist die verarbeitete Ursprungsnachricht keine Edifact, sondern ein edi-json, so wird dieses direkt zurückgegeben. Im Fall einer Edifact spricht die B2B mit dieser dann den edi-json.converter Microservice an, um diese in ein edi-json zu mappen.

Für die v2 des edi-json Konvertierungsservices wurde die Schnittstelle edifactjson um den Parameter “ignoreSegmentIdentifyErrors” erweitert. Wird hierfür “true” angegeben, werden evtl. auftretende Probleme mit der EDIFACT-Struktur ignoriert. Dies ist der Standardfall. Wird “false” angegeben, werden diese Probleme als Fehler behandelt und die Konvertierung wird abgebrochen. Im Fehler fall wird ein HTTP-500 Fehler mit der entsprechenden Fehlermeldung zurückgegeben.

Dieser REST Endpunkt unterscheidet dabei die folgenden Fehlerklassen für den Fall, dass bei der Anfrage kein edi-json erfolgreich zurückgegeben werden kann:

Fehlerfall HTTP Status Fehlerklasse (Response-Body -> details)
Autorisierung an B2B fehlgeschlagen 403 ACCESS_DENIED - Access is denied
MessageId aus Abfrage ist in B2B DB nicht vorhanden oder vorhandener aber hat keine Ursprungsnachricht (BASE_MESSAGE) z.B. Job-Eintrag 404 MESSAGE_ID_NOT_FOUND - MessageId not found
Ursprungsnachricht (BASE_MESSAGE) zu MessageId ist weder eine Edifact oder ein edi-json 404 WRONG_MESSAGE_FORMAT - The message is neither an edifact nor an edi-json
Edifact zur der Nachricht konnte nicht erfolgreich vom edi-json.converter gemappt werden 500 EDIFACT_CONVERSION_FAILURE - Edifact to edi-json conversion failed
edi-json.converter ist (vom B2B) nicht erreichbar 500 CONVERTER_EXCEPTION - Edi-json converter is unavailable or could not handle the requested message
edi-json.converter ist in B2B nicht konfiguriert 500 CONVERTER_NOT_CUSTOMIZED - This service is inoperational because the global property EDIJSON_CONVERTER_URL could not be read
B2B nicht erreichbar 500 kein B2B Fehlercode Body
B2B DB Fehler/nicht erreichbar 503 B2B_DATABASE_UNAVAILABLE - B2B database is not available

Seine Base URL muss dazu in der folgenden GlobalProperty hinterlegt sein.

EDIJSON_CONVERTER_URL = http://<converter_server>:<converter_port>

Der HATEOAS-Wrapper der B2B bei der JSON Convertierung hat die folgende Struktur:

{
  "data": "edi-json",
  "links": []
}

Es können nur nicht archivierte Nachrichten, bei denen das Attribut B3P_BASE_MESSAGE eine Edifact Nachricht enthält abgerufen werden.

Backend -> Markt (JSON -> Edifact)

SXP-Outbound

Die Edifacts werden im definierten JSON Format (gemäß edi-json-model, inklusive Hateoas-Wrapper) mit UTF-8 Encoding per POST an den Endpunkt (tatsächliche Adresse über Swagger einsehbar) gesendet.

POST [b2b]/api/edifactjson/v1/queue/{priority}

Wird keine Priorität angegeben nimmt die B2B als default-Wert LOW an. Dies entspricht dem üblichen Default-Wert. In der B2B muss dazu ein passiver Pseudo-Inbound-Service angelegt werden, der die Nachrichtenverabeitung mit einem bestimmten Channel in Queue leitet.

InboundEdiJsonService

Die ID des Services kann abweichend vom Defaultwert in der folgenden GlobalProperty definiert werden, welche nach Neustart aktiv wird:

INBOUND_EDIJSON_SERVICE = My_Json_Inbound_Service (Default: EdiJsonInbound)

Noch vor der Queue durchläuft das JSON die Formaterkennung, welche aus den unterstützten JSON Formate in der HATEOAS-Wrapper Struktur die entsprechenden Daten auslesen kann. (Im Formatobjekt ist das Attribut UtilRef nicht befüllt.) Nachdem die Nachricht in der Queue abgelegt wurde wird der Request beendet und die Id der neuen Nachricht im ResponseBody zurück geschickt. Die Verarbeitung der Nachricht hat zu diesem Zeitpunkt noch nicht begonnen. Die zurückgegebene ID hat die folgende Form:

<B2BMessageId>_<B2BQueueId>

Die Konvertierung findet hier innerhalb eines Outbound-Channels statt, in welchem die Action EdiJson2EdifactMappingAction konfiguriert werden muss.

Debuggen

  • in der docker-compose.yml die Zeilen unter # debug aktivieren
    • bei ports
    • bei environment
  • Debugger konfigurieren
    • Datei liegt unter: .runConfigurations/localhost_5005.run.xml
    • diese als Debug-Konfiguration verwenden
      • (IntelliJ Ultimate: Datei im Viewer anschauen, oberhalb des Codes Hinweis “Open Run/Debug Configurations” anklicken
  • Breakpoints setzen
  • Container starten
  • Debugger in IDE starten
  • Rest-Calls durchführen (z. B. mit rest-api.http in IntelliJ)
  • Programmlauf stoppt an Breakpoints
View Me   Edit Me