Files
123123/ZA.CoreService.ESBCertificateManager/Tools/SonicMfContainerTool.java
T

689 lines
17 KiB
Java

import java.lang.reflect.Method;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;
import javax.management.ObjectName;
/**
* Sonic-MfApi-Hilfsprogramm.
*
* Befehle:
* validate - Anmeldung + lesender Container-Zugriff
* restart - Container neu starten (stop/restart)
* list - Container der Domain auflisten
*
* javac -source 8 -target 8 SonicMfContainerTool.java
*/
public final class SonicMfContainerTool
{
public static final String TOOL_VERSION =
"2026-07-29-validate-restart-list";
public static void main(String[] args)
{
info("ToolVersion=" + TOOL_VERSION);
try
{
Args parsedArguments = Args.parse(args);
if (!"validate".equals(parsedArguments.command)
&& !"restart".equals(parsedArguments.command)
&& !"list".equals(parsedArguments.command))
{
fail(
"Usage: SonicMfContainerTool "
+ "<validate|restart|list> "
+ "--domain D "
+ "--url U "
+ "--user U "
+ "[--container C] "
+ "[--timeout SEC]");
return;
}
if (isBlank(parsedArguments.domain)
|| isBlank(parsedArguments.url)
|| isBlank(parsedArguments.user))
{
fail("domain, url und user sind Pflicht.");
return;
}
boolean needsContainer =
"validate".equals(parsedArguments.command)
|| "restart".equals(parsedArguments.command);
if (needsContainer
&& isBlank(parsedArguments.container))
{
fail("container ist Pflicht fuer validate/restart.");
return;
}
if (isBlank(parsedArguments.password))
{
fail(
"Das Sonic-Kennwort wurde nicht ueber "
+ "ESB_SONIC_PASSWORD bereitgestellt.");
return;
}
long timeoutMilliseconds = Math.max(
5_000L,
parsedArguments.timeoutSec * 1000L);
Object connector = connect(
parsedArguments.url,
parsedArguments.user,
parsedArguments.password,
timeoutMilliseconds);
try
{
if ("list".equals(parsedArguments.command))
{
listContainers(
connector,
parsedArguments.domain);
}
else if ("validate".equals(
parsedArguments.command))
{
validateConnection(
connector,
parsedArguments.domain,
parsedArguments.container);
}
else
{
restart(
connector,
parsedArguments.domain,
parsedArguments.container);
}
}
finally
{
disconnect(connector);
}
}
catch (Throwable throwable)
{
Throwable root = rootOf(throwable);
String message = root.getMessage();
if (message == null)
{
message = "(keine Detailmeldung)";
}
fail(
root.getClass().getName()
+ ": "
+ message);
}
}
private static void listContainers(
Object connector,
String domain)
throws Exception
{
Method queryNamesMethod =
findMethod(
connector.getClass(),
"queryNames",
new Class[]
{
ObjectName.class,
javax.management.QueryExp.class
});
if (queryNamesMethod == null)
{
throw new IllegalStateException(
"queryNames(ObjectName, QueryExp) wurde nicht gefunden.");
}
ObjectName pattern =
new ObjectName("*:ID=AGENT");
Object rawResult = queryNamesMethod.invoke(
connector,
new Object[]
{
pattern,
null
});
if (!(rawResult instanceof Set))
{
throw new IllegalStateException(
"queryNames lieferte kein Set.");
}
Set names = (Set) rawResult;
String domainPrefix = domain + ".";
int count = 0;
System.out.println("OK:ContainerListBegin");
Iterator iterator = names.iterator();
while (iterator.hasNext())
{
Object entry = iterator.next();
if (!(entry instanceof ObjectName))
{
continue;
}
ObjectName objectName = (ObjectName) entry;
String canonical = objectName.getCanonicalName();
if (canonical == null)
{
continue;
}
// Erwartet: domain.containerName:ID=AGENT
if (!canonical.regionMatches(
true,
0,
domainPrefix,
0,
domainPrefix.length()))
{
continue;
}
int colon = canonical.indexOf(':');
if (colon <= domainPrefix.length())
{
continue;
}
String containerName =
canonical.substring(
domainPrefix.length(),
colon);
if (isBlank(containerName))
{
continue;
}
System.out.println(
"CONTAINER="
+ containerName.trim());
count++;
}
System.out.println(
"OK:ContainerListEnd count="
+ count
+ " domain="
+ domain
+ " tool="
+ TOOL_VERSION);
System.out.flush();
}
private static Object connect(
String url,
String user,
String password,
long timeoutMilliseconds)
throws Exception
{
Hashtable environment = new Hashtable();
environment.put("ConnectionURLs", url);
environment.put("DefaultUser", user);
environment.put("DefaultPassword", password);
Class addressClass = Class.forName(
"com.sonicsw.mf.jmx.client.JMSConnectorAddress");
Object address = addressClass
.getConstructor(
new Class[]
{
Hashtable.class
})
.newInstance(
new Object[]
{
environment
});
Class clientClass = Class.forName(
"com.sonicsw.mf.jmx.client.JMSConnectorClient");
Object connector = clientClass
.getConstructor(new Class[] {})
.newInstance(new Object[] {});
trySetTimeout(connector, timeoutMilliseconds);
Method connectMethod = findConnect(clientClass);
if (connectMethod == null)
{
throw new IllegalStateException(
"JMSConnectorClient.connect(...) wurde nicht gefunden.");
}
Class[] parameterTypes =
connectMethod.getParameterTypes();
if (parameterTypes.length == 2)
{
connectMethod.invoke(
connector,
new Object[]
{
address,
boxTimeout(
parameterTypes[1],
timeoutMilliseconds)
});
}
else
{
connectMethod.invoke(
connector,
new Object[]
{
address
});
}
return connector;
}
private static void validateConnection(
Object connector,
String domain,
String container)
throws Exception
{
String shortName = shortContainer(container);
ObjectName objectName = new ObjectName(
domain + "." + shortName + ":ID=AGENT");
info("ValidatingObjectName=" + objectName);
Method getMBeanInfoMethod =
findMethod(
connector.getClass(),
"getMBeanInfo",
new Class[]
{
ObjectName.class
});
if (getMBeanInfoMethod == null)
{
throw new IllegalStateException(
"getMBeanInfo(ObjectName) wurde nicht gefunden.");
}
Object result = getMBeanInfoMethod.invoke(
connector,
new Object[]
{
objectName
});
if (result == null)
{
throw new IllegalStateException(
"Die Container-MBean konnte nicht gelesen werden.");
}
System.out.println(
"OK:ConnectionValidated"
+ " container="
+ shortName
+ " domain="
+ domain
+ " tool="
+ TOOL_VERSION);
System.out.flush();
}
private static void restart(
Object connector,
String domain,
String container)
throws Exception
{
String shortName = shortContainer(container);
ObjectName objectName = new ObjectName(
domain + "." + shortName + ":ID=AGENT");
info("ObjectName=" + objectName);
StringBuffer attempts = new StringBuffer();
String[] operations = new String[]
{
"stop",
"restart"
};
for (int index = 0; index < operations.length; index++)
{
String operation = operations[index];
try
{
info("Trying MBean.invoke(" + operation + ")");
invokeNoArgs(connector, objectName, operation);
okRestart("MBean." + operation, shortName, domain);
return;
}
catch (Throwable throwable)
{
Throwable root = rootOf(throwable);
String line =
"MBean."
+ operation
+ " => "
+ root.getClass().getName()
+ ": "
+ root.getMessage();
warn(line);
attempts.append(line).append('\n');
}
}
throw new IllegalStateException(
"Neustart fehlgeschlagen:\n" + attempts.toString());
}
private static void invokeNoArgs(
Object connector,
ObjectName objectName,
String operation)
throws Exception
{
Method invokeMethod =
findMethod(
connector.getClass(),
"invoke",
new Class[]
{
ObjectName.class,
String.class,
Object[].class,
String[].class
});
if (invokeMethod == null)
{
throw new IllegalStateException(
"invoke(...) wurde nicht gefunden.");
}
invokeMethod.invoke(
connector,
new Object[]
{
objectName,
operation,
null,
null
});
}
private static void okRestart(
String path,
String container,
String domain)
{
System.out.println(
"OK:RestartInvoked"
+ " path="
+ path
+ " container="
+ container
+ " domain="
+ domain
+ " tool="
+ TOOL_VERSION);
System.out.flush();
}
private static void disconnect(Object connector)
{
try
{
Method method =
findMethod(
connector.getClass(),
"disconnect",
new Class[] {});
if (method != null)
{
method.invoke(connector, new Object[] {});
}
}
catch (Throwable ignored)
{
}
}
private static void trySetTimeout(
Object connector,
long timeoutMilliseconds)
{
try
{
Method method =
findMethod(
connector.getClass(),
"setTimeout",
new Class[]
{
Long.TYPE
});
if (method != null)
{
method.invoke(
connector,
new Object[]
{
Long.valueOf(timeoutMilliseconds)
});
}
}
catch (Throwable ignored)
{
}
}
private static Method findConnect(Class clientClass)
{
Method[] methods = clientClass.getMethods();
for (int index = 0; index < methods.length; index++)
{
Method method = methods[index];
if (!"connect".equals(method.getName()))
{
continue;
}
Class[] types = method.getParameterTypes();
if (types.length == 1 || types.length == 2)
{
return method;
}
}
return null;
}
private static Method findMethod(
Class type,
String name,
Class[] parameterTypes)
{
try
{
return type.getMethod(name, parameterTypes);
}
catch (NoSuchMethodException exception)
{
return null;
}
}
private static Object boxTimeout(
Class parameterType,
long timeoutMilliseconds)
{
if (parameterType == Integer.TYPE
|| parameterType == Integer.class)
{
long seconds =
Math.max(1L, timeoutMilliseconds / 1000L);
if (seconds > Integer.MAX_VALUE)
{
seconds = Integer.MAX_VALUE;
}
return Integer.valueOf((int) seconds);
}
return Long.valueOf(timeoutMilliseconds);
}
private static String shortContainer(String container)
{
String value = container.trim();
int colon = value.indexOf(':');
if (colon > 0)
{
value = value.substring(0, colon);
}
int dot = value.lastIndexOf('.');
if (dot >= 0 && dot < value.length() - 1)
{
value = value.substring(dot + 1);
}
return value;
}
private static Throwable rootOf(Throwable throwable)
{
Throwable current = throwable;
while (current.getCause() != null
&& current.getCause() != current)
{
current = current.getCause();
}
return current;
}
private static boolean isBlank(String value)
{
return value == null || value.trim().length() == 0;
}
private static void info(String message)
{
System.err.println("INFO: " + message);
}
private static void warn(String message)
{
System.err.println("WARN: " + message);
}
private static void fail(String message)
{
System.err.println("ERROR: " + message);
System.exit(1);
}
private static final class Args
{
private String command;
private String domain;
private String url;
private String user;
private String password;
private String container;
private int timeoutSec = 60;
private static Args parse(String[] args)
{
Args result = new Args();
if (args == null || args.length == 0)
{
fail("Kein Befehl angegeben.");
}
result.command = args[0];
result.password =
System.getenv("ESB_SONIC_PASSWORD");
for (int index = 1; index < args.length; index++)
{
String token = args[index];
if ("--domain".equals(token) && index + 1 < args.length)
{
result.domain = args[++index];
}
else if ("--url".equals(token) && index + 1 < args.length)
{
result.url = args[++index];
}
else if ("--user".equals(token) && index + 1 < args.length)
{
result.user = args[++index];
}
else if ("--container".equals(token)
&& index + 1 < args.length)
{
result.container = args[++index];
}
else if ("--timeout".equals(token)
&& index + 1 < args.length)
{
result.timeoutSec =
Integer.parseInt(args[++index]);
}
}
return result;
}
}
}