eeg_portal/docs/PLAN-EDA-KOMMUNIKATION.md
Bernhard Müller 459f976b67 feat(mako): add email-based EDA communication
- Add EmailEdaConsentService for prod consent requests via SMTP
- Add EdaMailSender, EdaMailParser, EdaMailPoller for IMAP polling
- Polling interval: 15 min (configurable via eda.email.poll-interval-ms)
- Consumption data ingestion from XLSX email attachments
- Add @Profile('!prod') to SimulatedEda*Services as fallback
- Add EMAIL_AUTO to DataSource enum for automated email imports
- Add EDA email configuration to application-prod.yml and application-dev.yml
- Add unit tests for all new services
- Add docs/PLAN-EDA-KOMMUNIKATION.md with full implementation plan

All 232 tests passing.
2026-07-25 15:29:43 +02:00

8.5 KiB

Plan: E-Mail-basierte EDA-Kommunikation

Ziel

Ersetze die aktuelle vollständige EDA-Simulation durch eine reale E-Mail-basierte Kommunikation mit dem EDA-Netzwerk (Netzbetreiber). Simulator bleibt als @Profile("!prod")-Fallback. Architektur erlaubt später einfachen Wechsel zu Messenger-API.


Aktueller Stand

Was existiert

  • EdaConsentService (Interface) + SimulatedEdaConsentService (immer aktiv, kein @Profile)
  • EdaTopologyService (Interface) + SimulatedEdaTopologyService (immer aktiv)
  • MailService (Interface) für User-Verifizierung, nicht für EDA
  • spring-boot-starter-restclient im pom.xml (nicht verwendet)
  • DataSource-Enum hat EMAIL_XLSX aber kein automatisches E-Mail-Polling
  • Kommentar in EdaCommunicationEventListener:66: "entweder via Webhook oder Mailbox"

Was fehlt

  • Keine reale EDA-Kommunikation (kein HTTP, kein E-Mail-Versand an EDA)
  • Keine automatische Verbrauchsdaten-Ingestion via E-Mail
  • Simulator hat kein @Profile - immer aktiv, auch in prod

Architektur-Entscheidung: Strategy Pattern

                        ┌─────────────────────────┐
                        │   EdaConsentService      │  (Interface - bleibt unverändert)
                        │   EdaTopologyService     │
                        └─────────┬───────────────┘
                                  │
              ┌───────────────────┼───────────────────┐
              │                   │                   │
    ┌─────────▼──────────┐ ┌─────▼───────────┐ ┌────▼──────────────┐
    │ SimulatedEda*      │ │ EmailEda*       │ │ MessengerEda*     │
    │ @Profile("!prod")  │ │ @Profile("prod")│ │ (später)          │
    └────────────────────┘ └─────────────────┘ └───────────────────┘

Umsetzungs-Schritte

Schritt 1: Simulator mit @Profile versehen

Dateien:

  • eeg_backend/.../mako/service/impl/SimulatedEdaConsentService.java
  • eeg_backend/.../mako/service/impl/SimulatedEdaTopologyService.java

Änderung:

// Vorher:
@Service
public class SimulatedEdaConsentService implements EdaConsentService {

// Nachher:
@Profile("!prod")
@Service
public class SimulatedEdaConsentService implements EdaConsentService {

Hinweis: @Profile("!prod") statt @Profile("dev") - so sind die Simulatoren auch ohne Profil (z.B. in Tests) verfügbar. Die EdaCommunicationEventListener hat kein Profil und braucht immer einen EdaConsentService + EdaTopologyService.


Schritt 2: EDA E-Mail-Konfiguration

application-prod.yml (ergänzen):

eda:
  email:
    gateway-address: ${EDA_GATEWAY_EMAIL:eda-gateway@example.com}
    poll-interval-ms: ${EDA_POLL_INTERVAL_MS:900000}
    imap:
      host: ${EDA_IMAP_HOST:}
      port: ${EDA_IMAP_PORT:993}
      username: ${EDA_IMAP_USERNAME:}
      password: ${EDA_IMAP_PASSWORD:}
      folder: INBOX
      protocol: imaps
    smtp:
      host: ${EDA_SMTP_HOST:}
      port: ${EDA_SMTP_PORT:587}
      username: ${EDA_SMTP_USERNAME:}
      password: ${EDA_SMTP_PASSWORD:}

application-dev.yml (ergänzen):

eda:
  email:
    gateway-address: test-eda@example.com
    poll-interval-ms: 900000

EDA-E-Mail-Format (Hinweis)

Das EDA-Netzwerk (Elektrizitäts-Daten-Austausch) in Österreich nutzt für E-Mail-Kommunikation typischerweise:

  • Betreff: Strukturiert mit AT-Nummer + Nachrichtentyp (z.B. CMRequest|AT... für Consent)
  • Body: XML oder strukturiertes Textformat mit AT-Nummer, Entscheidung, Referenz-ID
  • Attachments: XLSX/CSV für Verbrauchsdaten
  • Zentraler Empfänger: EDA-Gateway leitet an Netzbetreiber weiter (wie beim Messenger)

Die genaue Spezifikation muss vom EDA-Gateway-Anbieter bestätigt werden. Die Architektur ist flexibel gehalten.

Neue Dateien

EmailEdaConsentService.java - Prod Consent via SMTP:

  • @Profile("prod")
  • Implementiert EdaConsentService
  • sendConsentRequest():
    1. Baut Consent-E-Mail auf (AT-Nummer, Typ, Portal-Referenz-ID)
    2. Versendet an eda.email.gateway-address via SMTP
    3. Speichert Request-Metadaten für Zuordnung der Antwort
    4. Logging

EdaMailSender.java - E-Mail-Versand:

  • Hilfsklasse zum Aufbau und Versand von EDA-E-Mails
  • Consent-Request-E-Mail Vorlage (XML-Format)
  • @Async für nicht-blockierenden Versand

EdaMailParser.java - E-Mail-Parsing:

  • Hilfsklasse zum Parsen von EDA-E-Mails
  • Erkennt E-Mail-Typ (Consent-Antwort vs. Verbrauchsdaten)
  • Extrahiert AT-Nummer, Entscheidung, Referenz-ID
  • Flexibel: E-Mail-Format-Konfiguration via Properties

EdaMailPoller.java - IMAP-Polling:

  • @Profile("prod")
  • @Scheduled(fixedDelayString = "${eda.email.poll-interval-ms:900000}") - alle 15 Minuten
  • Verbindet sich via IMAP zum EDA-Postfach
  • Parst eingehende E-Mails:
    • Consent-Antwort: Erkennt AT-Nummer + Entscheidung (approved/rejected)
    • Verbrauchsdaten-Attachment: Erkennt XLSX/CSV
  • Für Consent-Antworten:
    • Veröffentlicht MakoConsentApprovedEvent / MakoConsentRejectedEvent / MakoConsentTechnicalFailedEvent
  • Für Verbrauchsdaten:
    • Nutzt bestehenden XlsxMeteringDataParser für XLSX
    • Speichert via MeteringDataService
    • Erstellt MeteringDataUpload-Audit-Eintrag

Schritt 4: Verbrauchsdaten-Ingestion via E-Mail

Integration in EdaMailPoller:

Der Poller erkennt eingehende E-Mails mit Verbrauchsdaten-Attachments:

  1. Mail-Scan: Durchsucht Postfach nach neuen E-Mails mit Attachments
  2. Attachment-Erkennung: XLSX, CSV (je nach EDA-Standard)
  3. Parsing: Nutzt XlsxMeteringDataParser (bestehend)
  4. Speicherung: Ruft MeteringDataService.uploadMeteringData() auf
  5. Audit: Erstellt MeteringDataUpload mit DataSource.EMAIL_AUTO

DataSource erweitern:

  • DataSource.java - EMAIL_AUTO hinzugefügt

Schritt 5: Tests

Neue/angepasste Dateien:

  • EmailEdaConsentServiceTest.java - Mock SMTP, verify E-Mail-Inhalt
  • EdaMailParserTest.java - Test verschiedener E-Mail-Formate
  • EdaMailPollerTest.java - Unit-Test für Polling-Logik
  • SimulatorProfileTest.java - Verifiziere @Profile("!prod")

Datei-Übersicht

Aktion Datei
Ändern SimulatedEdaConsentService.java - @Profile("!prod")
Ändern SimulatedEdaTopologyService.java - @Profile("!prod")
Ändern application-prod.yml - EDA E-Mail-Konfiguration
Ändern application-dev.yml - EDA Dev-Konfiguration
Ändern DataSource.java - EMAIL_AUTO hinzufügen
Neu EmailEdaConsentService.java - Prod Consent via SMTP
Neu EdaMailSender.java - E-Mail-Versand
Neu EdaMailParser.java - E-Mail-Parsing
Neu EdaMailPoller.java - IMAP-Polling (15 Min) für Antworten + Verbrauchsdaten
Neu Tests

Verifizierung

  1. Dev-Modus: @Profile("!prod") aktiv → Simulator wird geladen, kein EDA-Mail-Poller
  2. Prod-Modus: @Profile("prod") aktiv → EmailEdaConsentService + EdaMailPoller werden geladen
  3. Unit-Tests: mvn test -pl eeg_backend - alle Tests grün (232 Tests)
  4. Integrationstest:
    • Dev: Konsistenter Flow mit Simulator (AT-Nummer endet mit REJECT/ERROR)
    • Prod: Echte SMTP/IMAP-Verbindung testen (kann mit Test-Server)
  5. Manuell prüfen:
    • Consent-Flow: User registrieren → Admin genehmigen → MeteringPoint wechselt zu WAITING_FOR_CONSENT
    • Simulator: AT-Nummer "AT0010001234567890123456789012345" → Consent Approved nach Delay
    • E-Mail: Echte E-Mail wird an Gateway gesendet

Offene Fragen

  1. EDA-Spezifikation: Die genaue E-Mail-Format-Spezifikation muss vom EDA-Gateway-Anbieter bezogen werden. Die Architektur ist flexibel gehalten (Konfiguration via Properties).
  2. Polling-Intervall: Entschieden: alle 15 Minuten (Standardwert in Konfiguration, konfigurierbar).
  3. Fehlerbehandlung: Was passiert bei nicht zuordenbaren E-Mails? (Log + Flag) - Muss noch definiert werden.
  4. Verbrauchsdaten-Format: XLSX oder CSV? (XLSX-Parsing existiert bereits) - Muss mit EDA-Gateway-Anbieter abgestimmt werden.

Implementierungsstand

Status: ABGESCHLOSSEN

Alle 6 Schritte wurden implementiert und alle 232 Tests bestehen.