Files
123123/ZA.CoreService.ESBCertificateManager/Tools/SonicMfContainerTool.java
T
GizzlerandCursor c73f53d740 Slim MfApi stack to restart-only path.
Drop ping/list discovery, WinRM scripts, and heavy Java probing so only KnownContainers + MBean restart remain.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-24 12:32:05 +02:00

296 lines
9.2 KiB
Java

import java.lang.reflect.Method;
import java.util.Hashtable;
import javax.management.ObjectName;
/**
* Minimaler Sonic-Restart (wie SMC): JMSConnectorClient + MBean stop/restart.
* Compile: javac --release 8 SonicMfContainerTool.java
*/
public final class SonicMfContainerTool
{
public static final String TOOL_VERSION = "2026-07-24d-restart-only";
public static void main(String[] args)
{
info("ToolVersion=" + TOOL_VERSION);
try
{
Args a = Args.parse(args);
if (!"restart".equals(a.command))
{
fail("Usage: SonicMfContainerTool restart --domain D --url U --user U --container C [--timeout SEC]");
return;
}
if (isBlank(a.domain) || isBlank(a.url) || isBlank(a.user) || isBlank(a.container))
{
fail("domain, url, user und container sind Pflicht.");
return;
}
long timeoutMs = Math.max(5_000L, a.timeoutSec * 1000L);
Object connector = connect(a.url, a.user, a.password, timeoutMs);
try
{
restart(connector, a.domain, a.container);
}
finally
{
try
{
connector.getClass().getMethod("disconnect").invoke(connector);
}
catch (Exception ignore)
{
/* ignore */
}
}
}
catch (Throwable t)
{
fail(rootOf(t).getClass().getName() + ": " + rootOf(t).getMessage());
}
}
private static Object connect(String url, String user, String password, long timeoutMs) throws Exception
{
Hashtable env = new Hashtable();
env.put("ConnectionURLs", url);
env.put("DefaultUser", user);
env.put("DefaultPassword", password == null ? "" : password);
Class addressCl = Class.forName("com.sonicsw.mf.jmx.client.JMSConnectorAddress");
Object address = addressCl.getConstructor(new Class[] { Hashtable.class }).newInstance(new Object[] { env });
Class clientCl = Class.forName("com.sonicsw.mf.jmx.client.JMSConnectorClient");
Object connector = clientCl.getConstructor(new Class[] {}).newInstance(new Object[] {});
trySetTimeout(connector, timeoutMs);
Method connect = findConnect(clientCl);
if (connect == null)
{
fail("JMSConnectorClient.connect(...) nicht gefunden.");
return null;
}
Class[] pts = connect.getParameterTypes();
if (pts.length == 2)
{
connect.invoke(connector, new Object[] { address, boxTimeout(pts[1], timeoutMs) });
}
else
{
connect.invoke(connector, new Object[] { address });
}
return connector;
}
private static void restart(Object connector, String domain, String container) throws Exception
{
String shortName = shortContainer(container);
ObjectName on = new ObjectName(domain + "." + shortName + ":ID=AGENT");
info("ObjectName=" + on);
StringBuffer attempts = new StringBuffer();
String[] ops = new String[] { "stop", "restart" };
for (int i = 0; i < ops.length; i++)
{
String op = ops[i];
try
{
info("Trying MBean.invoke(" + op + ")");
invokeNoArgs(connector, on, op);
okRestart("MBean." + op, shortName, domain);
return;
}
catch (Throwable t)
{
Throwable root = rootOf(t);
String line = "MBean." + op + " => " + root.getClass().getName() + ": " + root.getMessage();
warn(line);
attempts.append(line).append('\n');
if ("stop".equals(op) && looksLikeStopSideEffect(root))
{
okRestart("MBean.stop(side-effect)", shortName, domain);
return;
}
}
}
fail("Neustart fehlgeschlagen. ToolVersion=" + TOOL_VERSION + "\nAttempts:\n" + attempts.toString());
}
private static void invokeNoArgs(Object connector, ObjectName on, String op) throws Exception
{
Method invoke = connector.getClass().getMethod("invoke", new Class[] {
ObjectName.class, String.class, Object[].class, String[].class
});
invoke.invoke(connector, new Object[] { on, op, new Object[0], new String[0] });
}
private static boolean looksLikeStopSideEffect(Throwable root)
{
if (root == null || root.getMessage() == null)
{
return false;
}
String m = root.getMessage().toLowerCase();
return m.indexOf("disconnect") >= 0
|| m.indexOf("closed") >= 0
|| m.indexOf("not connected") >= 0
|| m.indexOf("connection lost") >= 0;
}
private static void okRestart(String method, String shortName, String domain)
{
System.out.println("OK:RestartInvoked method=" + method
+ " container=" + shortName + " domain=" + domain
+ " tool=" + TOOL_VERSION);
System.out.flush();
}
private static Method findConnect(Class clientCl)
{
Method[] methods = clientCl.getMethods();
Method best = null;
for (int i = 0; i < methods.length; i++)
{
Method m = methods[i];
if (!"connect".equals(m.getName()))
{
continue;
}
Class[] pts = m.getParameterTypes();
if (pts.length == 1 || pts.length == 2)
{
best = m;
if (pts.length == 2)
{
return m;
}
}
}
return best;
}
private static void trySetTimeout(Object connector, long timeoutMs)
{
try
{
connector.getClass().getMethod("setTimeout", new Class[] { Long.TYPE })
.invoke(connector, new Object[] { Long.valueOf(timeoutMs) });
}
catch (Exception ignore)
{
try
{
connector.getClass().getMethod("setRequestTimeout", new Class[] { Long.TYPE })
.invoke(connector, new Object[] { Long.valueOf(timeoutMs) });
}
catch (Exception ignore2)
{
/* optional */
}
}
}
private static Object boxTimeout(Class type, long timeoutMs)
{
if (type == Integer.TYPE || type == Integer.class)
{
return Integer.valueOf((int) Math.min(Integer.MAX_VALUE, timeoutMs));
}
return Long.valueOf(timeoutMs);
}
private static String shortContainer(String container)
{
String c = container.trim();
int dot = c.lastIndexOf('.');
return dot >= 0 ? c.substring(dot + 1) : c;
}
private static Throwable rootOf(Throwable t)
{
Throwable cur = t;
while (cur.getCause() != null && cur.getCause() != cur)
{
cur = cur.getCause();
}
return cur;
}
private static boolean isBlank(String s)
{
return s == null || s.trim().length() == 0;
}
private static void info(String msg)
{
System.out.println("INFO:" + msg);
System.out.flush();
}
private static void warn(String msg)
{
System.out.println("WARN:" + msg);
System.out.flush();
}
private static void fail(String msg)
{
System.err.println("ERROR:" + msg);
System.err.flush();
System.exit(1);
}
private static final class Args
{
String command;
String domain;
String url;
String user;
String password;
String container;
int timeoutSec = 120;
static Args parse(String[] args)
{
Args a = new Args();
if (args == null || args.length == 0)
{
return a;
}
a.command = args[0];
for (int i = 1; i < args.length; i++)
{
String k = args[i];
String v = (i + 1 < args.length) ? args[i + 1] : null;
if ("--domain".equals(k) && v != null) { a.domain = v; i++; }
else if ("--url".equals(k) && v != null) { a.url = v; i++; }
else if ("--user".equals(k) && v != null) { a.user = v; i++; }
else if ("--password".equals(k) && v != null) { a.password = v; i++; }
else if ("--container".equals(k) && v != null) { a.container = v; i++; }
else if ("--timeout".equals(k) && v != null)
{
try { a.timeoutSec = Integer.parseInt(v); } catch (Exception ignore) { /* keep default */ }
i++;
}
}
if (isBlank(a.password))
{
String env = System.getenv("ESB_SONIC_PASSWORD");
if (!isBlank(env))
{
a.password = env;
}
}
return a;
}
}
private SonicMfContainerTool()
{
}
}