- 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.
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 EDAspring-boot-starter-restclientim pom.xml (nicht verwendet)DataSource-Enum hatEMAIL_XLSXaber 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.javaeeg_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
Schritt 3: E-Mail-basierte Consent-Implementierung
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():- Baut Consent-E-Mail auf (AT-Nummer, Typ, Portal-Referenz-ID)
- Versendet an
eda.email.gateway-addressvia SMTP - Speichert Request-Metadaten für Zuordnung der Antwort
- Logging
EdaMailSender.java - E-Mail-Versand:
- Hilfsklasse zum Aufbau und Versand von EDA-E-Mails
- Consent-Request-E-Mail Vorlage (XML-Format)
@Asyncfü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
- Veröffentlicht
- Für Verbrauchsdaten:
- Nutzt bestehenden
XlsxMeteringDataParserfür XLSX - Speichert via
MeteringDataService - Erstellt
MeteringDataUpload-Audit-Eintrag
- Nutzt bestehenden
Schritt 4: Verbrauchsdaten-Ingestion via E-Mail
Integration in EdaMailPoller:
Der Poller erkennt eingehende E-Mails mit Verbrauchsdaten-Attachments:
- Mail-Scan: Durchsucht Postfach nach neuen E-Mails mit Attachments
- Attachment-Erkennung: XLSX, CSV (je nach EDA-Standard)
- Parsing: Nutzt
XlsxMeteringDataParser(bestehend) - Speicherung: Ruft
MeteringDataService.uploadMeteringData()auf - Audit: Erstellt
MeteringDataUploadmitDataSource.EMAIL_AUTO
DataSource erweitern:
DataSource.java-EMAIL_AUTOhinzugefügt
Schritt 5: Tests
Neue/angepasste Dateien:
EmailEdaConsentServiceTest.java- Mock SMTP, verify E-Mail-InhaltEdaMailParserTest.java- Test verschiedener E-Mail-FormateEdaMailPollerTest.java- Unit-Test für Polling-LogikSimulatorProfileTest.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
- Dev-Modus:
@Profile("!prod")aktiv → Simulator wird geladen, kein EDA-Mail-Poller - Prod-Modus:
@Profile("prod")aktiv →EmailEdaConsentService+EdaMailPollerwerden geladen - Unit-Tests:
mvn test -pl eeg_backend- alle Tests grün (232 Tests) - Integrationstest:
- Dev: Konsistenter Flow mit Simulator (AT-Nummer endet mit REJECT/ERROR)
- Prod: Echte SMTP/IMAP-Verbindung testen (kann mit Test-Server)
- 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
- EDA-Spezifikation: Die genaue E-Mail-Format-Spezifikation muss vom EDA-Gateway-Anbieter bezogen werden. Die Architektur ist flexibel gehalten (Konfiguration via Properties).
- Polling-Intervall: Entschieden: alle 15 Minuten (Standardwert in Konfiguration, konfigurierbar).
- Fehlerbehandlung: Was passiert bei nicht zuordenbaren E-Mails? (Log + Flag) - Muss noch definiert werden.
- 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.