# 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:** ```java // 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):** ```yaml 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):** ```yaml 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()`: 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.