diff --git a/v8-9-10/Mail2FaxCleanup.class b/v8-9-10/Mail2FaxCleanup.class new file mode 100644 index 0000000..de8ba1b Binary files /dev/null and b/v8-9-10/Mail2FaxCleanup.class differ diff --git a/v8-9-10/Mail2FaxCleanup.java b/v8-9-10/Mail2FaxCleanup.java new file mode 100644 index 0000000..ac42082 --- /dev/null +++ b/v8-9-10/Mail2FaxCleanup.java @@ -0,0 +1,86 @@ +import de.vertico.starface.module.core.model.VariableType; +import de.vertico.starface.module.core.model.Visibility; +import de.vertico.starface.module.core.runtime.IBaseExecutable; +import de.vertico.starface.module.core.runtime.IRuntimeEnvironment; +import de.vertico.starface.module.core.runtime.annotations.Function; +import de.vertico.starface.module.core.runtime.annotations.OutputVar; + +import java.nio.file.*; + +/** + * Mail2FaxCleanup - Cleanup Block für Mail2Fax + * + * Dieser Block sollte beim "activate" Event des Moduls ausgeführt werden. + * Er stellt sicher, dass nach einem Server-Absturz oder Modul-Reload + * keine verwaisten Locks existieren. + * + * Hinweis: Der ReentrantLock ist ein In-Memory Lock und wird automatisch + * beim Server-Neustart freigegeben. Dieser Block ist hauptsächlich für + * Modul-Reloads ohne Server-Neustart gedacht. + * + * Für STARFACE 8.x, 9.x, 10.x (Java 21) + */ +@Function( + visibility = Visibility.Private, + description = "Cleanup für Mail2Fax - beim Modul-Start ausführen" +) +public class Mail2FaxCleanup implements IBaseExecutable { + + private static final String DATA_DIR = "/var/starface/module-data"; + + @OutputVar( + label = "Status", + description = "Cleanup-Status-Meldung", + type = VariableType.STRING + ) + public String statusMessage = ""; + + @Override + public void execute(IRuntimeEnvironment runtime) throws Exception { + org.apache.logging.log4j.Logger log = runtime.getLog(); + + try { + log.info("Mail2Fax Cleanup: Starte Cleanup"); + + // Datenverzeichnis prüfen + Path dataDir = Paths.get(DATA_DIR); + if (!Files.exists(dataDir)) { + log.info("Mail2Fax Cleanup: Datenverzeichnis existiert nicht, nichts zu tun"); + statusMessage = "OK - Keine Daten vorhanden"; + return; + } + + // Prüfe auf Tracking-Dateien + Path processedFile = Paths.get(DATA_DIR + "/mail2fax_processed.txt"); + Path retryFile = Paths.get(DATA_DIR + "/mail2fax_retry.txt"); + + int processedCount = 0; + int retryCount = 0; + + if (Files.exists(processedFile)) { + processedCount = Files.readAllLines(processedFile).size(); + } + + if (Files.exists(retryFile)) { + retryCount = (int) Files.lines(retryFile) + .filter(line -> !line.trim().isEmpty()) + .count(); + } + + log.info("Mail2Fax Cleanup: " + processedCount + " verarbeitete Nachrichten, " + + retryCount + " wartende Retries"); + + // Der ReentrantLock ist ein In-Memory Lock und existiert nur während + // der Laufzeit. Bei einem Server-Neustart oder Modul-Reload wird eine + // neue Instanz erstellt. Es gibt keine Lock-Datei die gelöscht werden muss. + + statusMessage = "OK - " + processedCount + " verarbeitete, " + retryCount + " Retries"; + log.info("Mail2Fax Cleanup: Abgeschlossen"); + + } catch (Exception e) { + String msg = "Cleanup-Fehler: " + e.getMessage(); + log.error("Mail2Fax Cleanup: " + msg, e); + statusMessage = msg; + } + } +} diff --git a/v8-9-10/README.md b/v8-9-10/README.md index d347653..9ef3691 100644 --- a/v8-9-10/README.md +++ b/v8-9-10/README.md @@ -19,7 +19,8 @@ Ein Custom Block für den STARFACE Module Designer, der E-Mails abruft und PDF-A ``` v8-9-10/ -├── Mail2FaxBlock.java # Quellcode des Custom Blocks +├── Mail2FaxBlock.java # Quellcode des Custom Blocks (Hauptfunktion) +├── Mail2FaxCleanup.java # Cleanup-Block (für activate Event) ├── build-block.sh # Kompilier-Script ├── libs/starface/ # STARFACE API JARs └── README.md @@ -40,7 +41,7 @@ cd .. ./build-block.sh ``` -Ergebnis: `Mail2FaxBlock.class` +Ergebnis: `Mail2FaxBlock.class` und `Mail2FaxCleanup.class` ## Installation im Module Designer @@ -49,14 +50,17 @@ Ergebnis: `Mail2FaxBlock.class` - "Neues Modul erstellen" - Name: "Mail2Fax" -### 2. Block hochladen +### 2. Blöcke hochladen - Tab "Ressourcen" - "Datei hochladen" → `Mail2FaxBlock.class` +- "Datei hochladen" → `Mail2FaxCleanup.class` -### 3. Funktion erstellen +### 3. Funktionen erstellen - Tab "Funktionen" -- Neue Funktion erstellen -- Den hochgeladenen Block als Implementierung auswählen +- **Funktion 1**: "Mail2Fax" (Hauptfunktion) + - Block: Mail2FaxBlock.class +- **Funktion 2**: "Mail2Fax Cleanup" (Cleanup) + - Block: Mail2FaxCleanup.class ### 4. Eingabe-Variablen konfigurieren @@ -77,19 +81,28 @@ Ergebnis: `Mail2FaxBlock.class` | maxRetries | NUMBER | Max. Wiederholungsversuche | 3 | | retryDelayMinutes | NUMBER | Minuten zwischen Versuchen | 5 | -### 5. Timer konfigurieren +### 5. Entrypoint konfigurieren (Cleanup) + +Damit nach einem Server-Absturz oder Modul-Reload keine Probleme auftreten: + +1. Tab **"Entrypoints"** öffnen +2. Event **"activate"** auswählen +3. **Mail2Fax Cleanup** Funktion verknüpfen + +Diese Funktion wird beim Modul-Start ausgeführt und stellt sicher, dass alles sauber initialisiert wird. + +### 6. Timer konfigurieren (Hauptfunktion) Der Block muss regelmäßig ausgeführt werden um E-Mails abzurufen. Dafür den Timer im Module Designer konfigurieren: 1. Tab **"Timer"** öffnen 2. Auf **[+]** klicken um einen neuen Schedule hinzuzufügen 3. Intervall festlegen (empfohlen: alle 60 Sekunden) - -![Timer-Tab im Module Designer](screenshots/timer-tab.png) +4. **Mail2Fax** Funktion (nicht Cleanup!) verknüpfen **Hinweis:** Der Block hat einen eingebauten Lock-Mechanismus. Wenn der Timer erneut auslöst während der Block noch läuft, wird die neue Ausführung automatisch übersprungen. Keine Gefahr von Duplikaten. -### 6. Modul aktivieren +### 7. Modul aktivieren ## Benutzung @@ -136,3 +149,18 @@ Da POP3 keine "gelesen"-Flags unterstützt, speichert der Block verarbeitete Mes - `/var/starface/module-data/mail2fax_processed.txt` So werden Duplikate vermieden, auch wenn E-Mails nicht sofort gelöscht werden können. + +## Lock-Mechanismus und Server-Absturz + +Der Block verwendet einen **In-Memory Lock** (`ReentrantLock`), um parallele Ausführungen zu verhindern. + +**Wichtig zu wissen:** +- Der Lock existiert nur im RAM, nicht als Datei +- Bei einem Server-Neustart wird der Lock automatisch freigegeben +- Bei einem Absturz während der Ausführung gibt es **keine verwaiste Lock-Datei** +- Der Cleanup-Block beim `activate` Event ist hauptsächlich für Log-Ausgaben und Statusprüfung + +**Was passiert bei einem Absturz während des Sendens?** +- Der Lock wird automatisch freigegeben (bei Neustart) +- PDFs in der Retry-Queue bleiben erhalten und werden beim nächsten Durchlauf erneut versucht +- Tracking-Dateien bleiben erhalten (processed.txt, retry.txt) diff --git a/v8-9-10/build-block.sh b/v8-9-10/build-block.sh index fa1ca75..b3e0908 100755 --- a/v8-9-10/build-block.sh +++ b/v8-9-10/build-block.sh @@ -57,21 +57,25 @@ if [ -z "$CLASSPATH" ]; then fi echo "Kompiliere Mail2FaxBlock.java..." - -# Kompilieren - wichtig: nur die .class Datei, kein Package! javac -source 21 -target 21 \ -cp "$CLASSPATH" \ -proc:none \ Mail2FaxBlock.java -if [ -f "Mail2FaxBlock.class" ]; then +echo "Kompiliere Mail2FaxCleanup.java..." +javac -source 21 -target 21 \ + -cp "$CLASSPATH" \ + -proc:none \ + Mail2FaxCleanup.java + +if [ -f "Mail2FaxBlock.class" ] && [ -f "Mail2FaxCleanup.class" ]; then echo "" echo "========================================" echo " Erfolgreich!" echo "========================================" echo "" - echo "Datei: Mail2FaxBlock.class" - ls -lh Mail2FaxBlock.class + echo "Dateien:" + ls -lh Mail2FaxBlock.class Mail2FaxCleanup.class echo "" echo "WICHTIG: Die JavaMail-Bibliothek muss auch auf der STARFACE sein!" echo "Falls Fehler auftreten, kopiere javax.mail.jar nach STARFACE:" @@ -80,9 +84,14 @@ if [ -f "Mail2FaxBlock.class" ]; then echo "Nächste Schritte:" echo "1. STARFACE Admin öffnen" echo "2. Module → Module Designer → Neues Modul" - echo "3. Unter 'Ressourcen' die Mail2FaxBlock.class hochladen" - echo "4. Neuen Funktionsbaustein erstellen und Block verknüpfen" - echo "5. Timer-Baustein hinzufügen für regelmäßige Ausführung" + echo "3. Unter 'Ressourcen' BEIDE .class Dateien hochladen:" + echo " - Mail2FaxBlock.class" + echo " - Mail2FaxCleanup.class" + echo "4. Zwei Funktionsbausteine erstellen:" + echo " - Mail2FaxBlock (Hauptfunktion für Timer)" + echo " - Mail2FaxCleanup (für 'activate' Entrypoint)" + echo "5. Timer-Baustein für Mail2FaxBlock hinzufügen" + echo "6. Entrypoint 'activate' mit Mail2FaxCleanup verknüpfen" echo "" else echo "FEHLER: Kompilierung fehlgeschlagen"