# MfApi-Restart – vollständige Erklärung Stand: Tool-Version `2026-07-24d-restart-only` Zweck dieses Dokuments: erklären, **wie die Sonic Management Application API (MfApi) in dieser App genutzt wird**, Schicht für Schicht – von Button-Klick bis MBean-Aufruf. --- ## 1. Was ist „die API“ hier? Es gibt **keine eigene REST-API** der WinForms-App. Gemeint ist die **Sonic / Aurea MF Management Application API** (wie in der Sonic Management Console, SMC): | Begriff | Bedeutung | |---------|-----------| | **MfApi** | Management Framework API über JMS/JMX-Client | | **Domain Manager** | zentrale Verwaltung der Sonic-Domain | | **Container / Agent** | laufende ESB-Instanz, z. B. `ct-ZADBService` | | **SMC** | Sonic Management Console (UI mit denselben Credentials/URL) | | **MBean** | verwaltbares Objekt im Domain Manager (`ObjectName`) | Die App startet lokal einen **Java-Prozess**, der die offiziellen Sonic-Client-JARs lädt und denselben Neustart-Intent ausführt wie **Restart** in der SMC. ### Warum Java und nicht reines .NET? Die Sonic-Client-Bibliotheken (`mgmt_client.jar`, `mfcontext.jar`, `sonic_Client.jar`, …) sind **Java**. C# orchestriert nur: Konfiguration lesen → `java.exe` starten → stdout auswerten. --- ## 2. Was die App bewusst *nicht* mehr macht Nach dem Slimming ist die API-Schicht **nur Restart**: | Entfernt | Früher | |----------|--------| | `ping` | Verbindungstest über Agent-Query | | `list` | Live-Containerliste aus dem Domain Manager | | IAgentProxy-Fallback | oft „Operation unsupported for unbounded client connector“ | | DomainManager-Scan | `restartContainer` / Manager-MBeans | | WinRM / `stopcontainer.bat` | lokaler Script-Pfad | | HTTP-REST-Pfade | ungenutzt | Container kommen ausschließlich aus **`appsettings.json` → `KnownContainers`**. --- ## 3. Architektur-Überblick ```text ┌─────────────────────────────────────────────────────────────────┐ │ WinForms UI (Form1) │ │ Button „ESB neu starten“ │ └────────────────────────────┬────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ DeploymentOrchestrator │ │ Preflight → Schleife über Ziele → Logging / Progress │ └────────────────────────────┬────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ RestartExecutor │ │ Ziel → SonicConnection (Name-Match) │ └────────────────────────────┬────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ SonicManagementClient │ │ Restart + PostRestartDelay │ └────────────────────────────┬────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ SonicMfApiExecutor (.NET) │ │ Java finden, Classpath bauen, Process starten, Output prüfen │ └────────────────────────────┬────────────────────────────────────┘ │ Process: java -cp … SonicMfContainerTool restart … ▼ ┌─────────────────────────────────────────────────────────────────┐ │ SonicMfContainerTool (Java) │ │ connect → MBean.invoke(stop|restart) → OK:RestartInvoked │ └────────────────────────────┬────────────────────────────────────┘ │ tcp://…:13070 (JMS Management) ▼ ┌─────────────────────────────────────────────────────────────────┐ │ Sonic Domain Manager / Broker │ │ ObjectName: proalpha-test.ct-ZADBService:ID=AGENT │ │ Launch Daemon startet Container nach stop ggf. neu │ └─────────────────────────────────────────────────────────────────┘ ``` --- ## 4. Konfiguration (`appsettings.json`) Beispiel (aktuell): ```json { "LogDirectory": "Logs", "SonicConnections": [ { "Name": "DE-Test", "DomainName": "proalpha-test", "ConnectionUrl": "tcp://dekun-painwbdet:13070", "Username": "Administrator", "Password": "Administrator", "SonicHome": "C:\\DEV\\MQ10.0", "JavaHome": "C:\\Program Files (x86)\\Java\\jre1.8.0_501", "JavaPath": "C:\\Program Files (x86)\\Java\\jre1.8.0_501\\bin\\java.exe", "MfClientLibPath": "C:\\DEV\\MQ10.0\\lib", "KnownContainers": [ "ct-ZADBService" ], "TimeoutSeconds": 120, "PostRestartDelaySeconds": 20 } ] } ``` ### Felder erklärt | Feld | Rolle | |------|--------| | **Name** | Alias der Verbindung. `DeploymentTarget.SonicConnectionName` muss dazu passen (hier `DE-Test`). | | **DomainName** | Sonic-Domain (`proalpha-test`). Teil des JMX-`ObjectName`. | | **ConnectionUrl** | Dieselbe TCP-URL wie in der SMC (`tcp://host:port`). | | **Username / Password** | SMC-Login (nicht Windows/WinRM). Passwort geht als Env `ESB_SONIC_PASSWORD` an Java. | | **SonicHome** | Installationsroot; Fallback für `lib\*.jar`, wenn `MfClientLibPath` leer/unbrauchbar. | | **JavaPath** | Bevorzugter Pfad zu `java.exe` (**Java 8+**, Class major ≥ 52). | | **JavaHome** | Alternativ `JavaHome\bin\java.exe`. | | **MfClientLibPath** | Ordner mit Client-JARs (`mgmt_client.jar`, `mfcontext.jar`, …). | | **KnownContainers** | Liste der Container-**Kurznamen** für die Grid-Ziele. | | **TimeoutSeconds** | Timeout für Java-Prozess und Tool-Connect (5–600 s, Clamp in Code). | | **PostRestartDelaySeconds** | Wartezeit **nach** erfolgreichem `OK:RestartInvoked` (0–120 s), bevor UI „fertig“ meldet. | ### Wichtige Namensunterscheidung | Name | Beispiel | Ist | |------|----------|-----| | Verbindungs-Alias | `DE-Test` | Eintrag in `SonicConnections[].Name` | | Domain | `proalpha-test` | Sonic-Domain | | Container | `ct-ZADBService` | Agent / Container in SMC | Häufiger Fehler: Alias `DE-Test` als Containername verwenden. Der ObjectName wäre dann falsch. Korrekt: ```text proalpha-test.ct-ZADBService:ID=AGENT ``` --- ## 5. Ziele (DeploymentTarget) Beim Start baut `SonicContainerDiscovery.BuildTargetsFromConfig()` aus jeder Connection und jedem `KnownContainers`-Eintrag ein Ziel: | Property | Quelle / Wert | |----------|----------------| | `Name` | `"DE-Test / ct-ZADBService"` | | `Environment` | `DomainName` | | `ContainerName` | `ct-ZADBService` | | `SonicConnectionName` | `DE-Test` | | `RestartType` | `SonicContainer` | Es gibt **keinen Live-Query** mehr („Container laden“ wurde entfernt). --- ## 6. Aufrufkette – jede Methode ### 6.1 UI – `Form1` | Schritt | Methode / Ereignis | Aufgabe | |---------|-------------------|---------| | 1 | `btnRestartOnly.Click` | Startet `RunRestartOnlyAsync()` | | 2 | `GetSelectedTargets()` | Angehakte Grid-Zeilen | | 3 | `_orchestrator.ValidateRestartOnly(...)` | Vorabprüfung | | 4 | MessageBox-Bestätigung | Nutzer bestätigt Neustart | | 5 | `_orchestrator.RestartOnlyAsync(...)` | eigentlicher Lauf | | 6 | Grid / Statuszeile | Ergebnis anzeigen (kein Erfolgs-Popup) | ### 6.2 `PreflightValidator.ValidateRestartOnly` Prüft grob: - mindestens ein Ziel gewählt - `ContainerName` gesetzt - `SonicConnectionName` gesetzt Fehler → Abbruch **vor** Java. ### 6.3 `DeploymentOrchestrator` | Methode | Aufgabe | |---------|---------| | `ValidateRestartOnly` | reicht an Preflight durch | | `RestartOnlyAsync` | Log öffnen, alle gewählten Ziele nacheinander | | `RestartTargetOnlyAsync` | Progress „Neustart…“ → Executor → `TargetStepResult` | Kein Deploy, kein TLS, kein SQL. ### 6.4 `RestartExecutor.ExecuteAsync` 1. `ContainerName` prüfen 2. `SonicConnection` per `Name == target.SonicConnectionName` finden 3. `new SonicManagementClient(connection)` 4. `RestartContainerAsync(target.ContainerName)` ### 6.5 `SonicManagementClient.RestartContainerAsync` 1. `_mfApi.RestartAsync(containerName)` 2. Bei Erfolg: `Task.Delay(PostRestartDelaySeconds)` 3. Status/Detail-String für UI/Log zurückgeben Die Verzögerung gibt dem Launch Daemon Zeit, den Container wieder hochzufahren. Sie ist **kein** aktiver SMC-Status-Poll. ### 6.6 `SonicMfApiExecutor` – die C#-Brücke #### `PrepareTool()` 1. **Java** über `ResolveJavaExe()`: - `JavaPath` - `JavaHome\bin\java.exe` - `JAVA_HOME` / `JRE_HOME` - `java.exe` aus PATH 2. **Classpath** über `ResolveSonicClasspath()`: - alle `*.jar` aus `MfClientLibPath`, sonst `SonicHome\lib` / `SonicHome` - bevorzugte Reihenfolge: `mgmt_client.jar`, `mfcontext.jar`, `sonic_Client.jar`, `sonic_Crypto.jar`, `mf_common.jar`, dann Rest 3. **Tool-Verzeichnis** mit `SonicMfContainerTool.class` (`Tools\` neben der EXE) Ergebnis-Classpath grob: ```text \Tools;\mgmt_client.jar;...; ``` #### `RestartAsync(containerName)` Startet: ```text java -cp ";" SonicMfContainerTool restart --domain proalpha-test --url tcp://dekun-painwbdet:13070 --user Administrator --container ct-ZADBService --timeout 120 ``` - Argumente über `ProcessStartInfo.ArgumentList` (keine manuellen Quotes → sonst Classpath-Bugs) - Passwort: Umgebungsvariable `ESB_SONIC_PASSWORD` - stdout/stderr lesen, auf Timeout killen #### Erfolgskriterium in C# Alles muss gelten: 1. `ExitCode == 0` 2. Ausgabe enthält `OK:RestartInvoked` 3. Ausgabe enthält **kein** `ERROR:` Sonst Fehlertext (+ Classpath-Hinweis bei `ClassNotFoundException` / `JMSConnectorAddress`). --- ## 7. Java-Tool – der eigentliche API-Call Datei: `Tools/SonicMfContainerTool.java` Bytecode: `Tools/SonicMfContainerTool.class` (Java 8 / major 52) Version-Stamp: `TOOL_VERSION = "2026-07-24d-restart-only"` (erste INFO-Zeile) ### 7.1 `main` 1. `INFO:ToolVersion=…` ausgeben 2. Args parsen – nur Befehl `restart` erlaubt 3. Pflicht: `--domain`, `--url`, `--user`, `--container` 4. Passwort: `--password` oder Env `ESB_SONIC_PASSWORD` 5. `connect(...)` 6. `restart(...)` 7. `disconnect` im `finally` ### 7.2 `connect` – Einloggen wie SMC ```text Hashtable env: ConnectionURLs = tcp://… DefaultUser = Administrator DefaultPassword = … JMSConnectorAddress(env) JMSConnectorClient() optional: setTimeout / setRequestTimeout client.connect(address [, timeout]) ``` Klassen (aus den JARs, per Reflection): - `com.sonicsw.mf.jmx.client.JMSConnectorAddress` - `com.sonicsw.mf.jmx.client.JMSConnectorClient` Reflection statt direkter Compile-Abhängigkeit: das Tool kompiliert ohne Sonic-JARs auf dem Build-Rechner; zur Laufzeit müssen die JARs im Classpath liegen. ### 7.3 `restart` – ObjectName und Lifecycle 1. Kurzname bilden (`proalpha-test.ct-ZADBService` → `ct-ZADBService`) 2. ObjectName: ```text .:ID=AGENT → proalpha-test.ct-ZADBService:ID=AGENT ``` 3. Operationen der Reihe nach: | Versuch | Operation | Bedeutung | |---------|-----------|-----------| | 1 | `stop` | Agent stoppen (SMC macht oft faktisch Stop; Daemon startet neu) | | 2 | `restart` | falls vorhanden und erlaubt | 4. Aufruf: ```text connector.invoke(objectName, op, new Object[0], new String[0]) ``` Das ist der JMX/`MBeanServerConnection.invoke`-Weg über den Sonic-Management-Connector. ### 7.4 Side-Effect bei `stop` Wenn `stop` eine Exception wirft, deren Message auf Verbindungsabbruch hindeutet (`disconnect`, `closed`, `not connected`, `connection lost`), wertet das Tool das als **Erfolg**: ```text OK:RestartInvoked method=MBean.stop(side-effect) … ``` Grund: der Agent geht runter und reißt oft die Management-Session – das ist erwartbar, kein „echter“ Fehlschlag. ### 7.5 Erfolgszeile ```text OK:RestartInvoked method=MBean.stop container=ct-ZADBService domain=proalpha-test tool=2026-07-24d-restart-only ``` C# sucht genau nach `OK:RestartInvoked`. ### 7.6 Ausgabe-Konventionen | Präfix | Bedeutung | |---------|-----------| | `INFO:` | Fortschritt / ObjectName / Trying … | | `WARN:` | fehlgeschlagener Versuch, Weiterversuch | | `ERROR:` | fatal, ExitCode ≠ 0 | | `OK:RestartInvoked` | Erfolg | --- ## 8. Sequenz (zeitlich) ```mermaid sequenceDiagram participant UI as Form1 participant Orch as DeploymentOrchestrator participant RE as RestartExecutor participant MC as SonicManagementClient participant EX as SonicMfApiExecutor participant JV as SonicMfContainerTool participant DM as Sonic Domain Manager UI->>Orch: RestartOnlyAsync(selected) Orch->>RE: ExecuteAsync(target) RE->>MC: RestartContainerAsync(ct-ZADBService) MC->>EX: RestartAsync(...) EX->>EX: PrepareTool (java + jars + class) EX->>JV: Process start restart … JV->>DM: JMSConnectorClient.connect JV->>DM: invoke(…:ID=AGENT, "stop") DM-->>JV: ok / disconnect side-effect JV-->>EX: OK:RestartInvoked EX-->>MC: Success=true MC->>MC: Delay PostRestartDelaySeconds MC-->>UI: Status + Detail ``` --- ## 9. Dateien und Verantwortlichkeiten | Datei | Rolle | |-------|--------| | `Form1.cs` | UI, Auswahl, Bestätigung, Status | | `Services/DeploymentOrchestrator.cs` | Lauf orchestrieren, Log | | `Services/PreflightValidator.cs` | Vorabprüfung | | `Services/RestartExecutor.cs` | Ziel → Connection | | `Services/SonicManagementClient.cs` | Restart + Delay | | `Services/SonicMfApiExecutor.cs` | Java-Prozess, Classpath, Erfolgsauswertung | | `Services/SonicContainerDiscovery.cs` | KnownContainers → Grid-Ziele | | `Models/SonicConnection.cs` | Konfigurationsmodell | | `Models/DeploymentTarget.cs` | Zielzeile | | `Tools/SonicMfContainerTool.java` | API-Client (Quellcode) | | `Tools/SonicMfContainerTool.class` | ausgeliefert / Java-8-Bytecode | | `appsettings.json` | Verbindungen + Containerliste | --- ## 10. Laufzeit-Voraussetzungen 1. **Java 8+** erreichbar (`JavaPath` empfohlen) 2. **`MfClientLibPath`** zeigt auf Ordner mit Sonic-Client-JARs 3. **`Tools\SonicMfContainerTool.class`** liegt neben der gebauten App 4. Netzwerk zu `ConnectionUrl` (Port z. B. 13070) 5. Gültige SMC-Credentials 6. Containername stimmt mit SMC überein (`ct-ZADBService`) 7. Domain Manager / Launch Daemon müssen Container nach Stop wieder starten können ### Tool neu kompilieren ```text javac --release 8 -encoding UTF-8 Tools\SonicMfContainerTool.java ``` (oder `-source 1.8 -target 1.8`) Danach App neu bauen, damit `.class` nach `bin\…\Tools\` kopiert wird (csproj Content-Copy). --- ## 11. Typische Fehler und Ursache | Symptom | Ursache | Maßnahme | |---------|---------|----------| | `ClassNotFoundException: JMSConnectorAddress` | Classpath ohne MF-JARs / falsche Quotes | `MfClientLibPath` prüfen; `ArgumentList` nicht manuell quoten | | `UnsupportedClassVersionError` | Runtime zu alt oder `.class` zu neu | Java 8+ Runtime; Tool mit `--release 8` bauen | | `Java nicht gefunden` | `JavaPath` falsch | appsettings korrigieren | | `Tools\SonicMfContainerTool.class nicht gefunden` | Build/Copy fehlt | Projekt neu bauen | | `Neustart fehlgeschlagen` + Attempts | MBean `stop`/`restart` abgelehnt | ObjectName/Rechte/Containerstatus in SMC prüfen | | Timeout | Domain Manager hängt / Netz | `TimeoutSeconds`, Firewall, Broker | | Falscher Container | Alias statt Kurzname | `KnownContainers`: `ct-ZADBService` | | Kein `ToolVersion=` in Output | alte/falsche `.class` | Tools neu kompilieren, Output-Ordner prüfen | --- ## 12. Verhältnis zur SMC | SMC | Diese App | |-----|-----------| | Login mit User/Pass auf Domain-URL | dieselben Werte in appsettings | | Container im Baum wählen | `KnownContainers` + Grid | | Rechtsklick → Restart | `MBean.invoke("stop"|"restart")` auf `…:ID=AGENT` | | UI zeigt Online/Offline | App wartet nur `PostRestartDelaySeconds`, pollt Status nicht | Operativ oft: **Stop am Agent-MBean**; der **Launch Daemon** bringt den Container wieder hoch – analog zu vielen SMC-Restart-Verhalten bei remote „unbounded“ Clients. Früher getestet: `IAgentProxy.restart()` schlägt remote häufig mit `Operation unsupported for unbounded client connector` fehl – deshalb der direkte MBean-Weg. --- ## 13. Sicherheitshinweise - Passwort steht in `appsettings.json` (Klartext) und kurzzeitig in der Prozess-Umgebung `ESB_SONIC_PASSWORD`. - Nicht in öffentliche Repos committen bzw. Secrets auslagern. - Logs (`LogDirectory`) können Tool-Output enthalten – ggf. sensible Zeilen beachten. --- ## 14. Manueller Test (ohne UI) Mit denselben Werten wie in appsettings: ```text set ESB_SONIC_PASSWORD=Administrator java -cp "Tools;C:\DEV\MQ10.0\lib\*" SonicMfContainerTool restart ^ --domain proalpha-test ^ --url tcp://dekun-painwbdet:13070 ^ --user Administrator ^ --container ct-ZADBService ^ --timeout 120 ``` Erwartet u. a.: ```text INFO:ToolVersion=2026-07-24d-restart-only INFO:ObjectName=proalpha-test.ct-ZADBService:ID=AGENT INFO:Trying MBean.invoke(stop) OK:RestartInvoked method=MBean.stop container=ct-ZADBService domain=proalpha-test tool=2026-07-24d-restart-only ``` (Unter Windows Classpath ggf. mit `;` und expliziten JAR-Namen statt `*`, je nach Shell.) --- ## 15. Kurzfassung 1. UI wählt Ziel aus `KnownContainers`. 2. C# findet die passenden Sonic-Verbindungsdaten. 3. C# startet Java mit MF-Client-JARs + `SonicMfContainerTool`. 4. Java verbindet sich wie die SMC an den Domain Manager. 5. Java ruft auf dem Agent-MBean `stop` (sonst `restart`) auf. 6. Bei `OK:RestartInvoked` wartet C# noch `PostRestartDelaySeconds` und meldet Erfolg. **Der einzige echte Sonic-API-Call der App ist:** `JMSConnectorClient.invoke(.:ID=AGENT, "stop"|"restart", …)`.