Advertisement
Guest User

Untitled

a guest
Sep 7th, 2017
501
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 22.15 KB | None | 0 0
  1. package org.jboss.performance.monitor;
  2.  
  3. import org.jboss.aesh.cl.CommandDefinition;
  4. import org.jboss.aesh.cl.Option;
  5. import org.jboss.aesh.cl.OptionList;
  6. import org.jboss.aesh.cl.completer.FileOptionCompleter;
  7. import org.jboss.aesh.cl.converter.CLConverter;
  8. import org.jboss.aesh.cl.validator.CommandValidator;
  9. import org.jboss.aesh.cl.validator.CommandValidatorException;
  10. import org.jboss.aesh.cl.validator.OptionValidator;
  11. import org.jboss.aesh.cl.validator.OptionValidatorException;
  12. import org.jboss.aesh.console.command.Command;
  13. import org.jboss.aesh.console.command.CommandOperation;
  14. import org.jboss.aesh.console.command.CommandResult;
  15. import org.jboss.aesh.console.command.ConsoleCommand;
  16. import org.jboss.aesh.console.command.invocation.CommandInvocation;
  17. import org.jboss.aesh.terminal.Key;
  18. import org.jboss.aesh.terminal.Shell;
  19. import org.jboss.as.controller.client.ModelControllerClient;
  20. import org.xml.sax.SAXException;
  21.  
  22. import javax.xml.parsers.ParserConfigurationException;
  23. import javax.xml.parsers.SAXParser;
  24. import javax.xml.parsers.SAXParserFactory;
  25. import java.io.File;
  26. import java.io.IOException;
  27. import java.io.PrintWriter;
  28. import java.net.InetAddress;
  29. import java.net.UnknownHostException;
  30. import java.util.ArrayList;
  31. import java.util.Arrays;
  32. import java.util.List;
  33. import java.util.jar.JarFile;
  34.  
  35. /**
  36. * @author <a href="mailto:stale.pedersen@jboss.org">Ståle W. Pedersen</a>
  37. */
  38. @CommandDefinition(name = "monitor",
  39. description = "Monitor JBoss resources",
  40. validator = MonitorResourcesCommand.MonitorValidator.class)
  41. public class MonitorResourcesCommand implements Command, ConsoleCommand {
  42.  
  43. private static org.jboss.logging.Logger logger = org.jboss.logging.Logger.getLogger(MonitorResourcesCommand.class);
  44.  
  45. private static final String[] deploymentSubsystemValues =
  46. new String[]{"ejb3", "jpa", "web", "webservices", "all", "none"};
  47.  
  48. private static final String[] subsystemValues =
  49. new String[]{"ejb3", "datasources", "web", "transactions", "messaging", "jca", "all", "none"};
  50.  
  51. @Option(shortName = 'h', hasValue = true,
  52. converter = InetConverter.class,
  53. description = "Host name of the server to be monitored (defaults to localhost). ")
  54. private InetAddress host;
  55.  
  56. @Option(shortName = 'p', hasValue = true, defaultValue = "9999",
  57. validator = PortValidator.class,
  58. description = "Port of the management interface, if not the default port. "
  59. + "Could be the port of the native interface of the domain controller.")
  60. private int port;
  61.  
  62. @Option(shortName = 'f', hasValue = true, required = true,
  63. completer = FileOptionCompleter.class,
  64. converter = PrintWriterConverter.class,
  65. defaultValue = "Filename to log usage statistics to.")
  66. private PrintWriter file;
  67.  
  68. @Option(shortName = 'i', hasValue = true, defaultValue = "1000",
  69. description = "Interval in milliseconds to gather usage statistics (defaults to once per second).")
  70. private long interval;
  71.  
  72. @Option(shortName = 't', hasValue = true, description = "Timestamp date format.", defaultValue = "HH:mm:ss:SSS")
  73. private String timestamp;
  74.  
  75. @Option(shortName = 'c', hasValue = true, description = "Configuration file for the standalone server you want to monitor.")
  76. private File config;
  77.  
  78. @OptionList(name = "domain-config", shortName = 'd', valueSeparator = ',',
  79. description = "Give the two configuration files, starting with the host configuration (e.g. host.xml), and then the domain.")
  80. private List<File> domainConfig;
  81.  
  82. @OptionList(shortName = 's', valueSeparator = ',',
  83. defaultValue = {"ejb3", "datasources", "web", "transactions", "messaging", "jca", "all", "none"},
  84. validator = SubsystemsValidator.class,
  85. description = "List of Subsystems you would like to monitor - valid values are threads, ejb3, datasources, web, transactions, "
  86. + "messaging, jca and all or none - defaults to all (none is for when you want to do monitoring of deployments only)")
  87. private List<String> subsystems;
  88.  
  89. @OptionList(name = "domain-server-names", shortName = 'n', valueSeparator = ',',
  90. description = "List of server names in a domain to monitor - values are the server names listed in host.xml, default to all "
  91. + "(based on what it finds in host.xml).")
  92. private List<String> domainServerNames;
  93.  
  94.  
  95. @OptionList(shortName = 'a', valueSeparator = ',',
  96. converter = JarFileConverter.class,
  97. description = "List of deployments (or applications) to monitor - values are the names of the deployments such as <name>.ear, "
  98. + "<name>.war, with the path information to read the files.")
  99. private List<JarFile> deployments;
  100.  
  101. @OptionList(name = "deployment-subsystems", shortName = 'b', valueSeparator = ',',
  102. defaultValue = {"ejb3", "jpa", "web", "webservices", "all", "none"},
  103. validator = DeploymentSubsystemsValidator.class,
  104. description = "List of subsystems, specific to your deployments, you would like to monitor - valid values are ejb3, jpa, web, webservices, "
  105. + "all or none - defaults to all (none is not valid if none is specified for subsystems)")
  106. private List<String> deploymentSubsystems;
  107.  
  108. @Option(name = "help", hasValue = false)
  109. private boolean help;
  110.  
  111. private boolean domainMode = false;
  112. private boolean deploymentsToMonitor = false;
  113. private String username;
  114. private String password;
  115. private boolean attached = false;
  116. private Status status = Status.DEFAULT;
  117. private ModelControllerClient client;
  118. private Monitor[] monitors;
  119. private ServerConfiguration serverConfiguration = null;
  120. private Shell shell;
  121.  
  122. public MonitorResourcesCommand() {
  123. }
  124.  
  125. public List<String> getSubsystems() {
  126. return subsystems;
  127. }
  128.  
  129. public List<String> getDomainServerNames() {
  130. return domainServerNames;
  131. }
  132.  
  133. public List<JarFile> getDeployments() {
  134. return deployments;
  135. }
  136.  
  137. public List<String> getDeploymentSubsystems() {
  138. return deploymentSubsystems;
  139. }
  140.  
  141. public File getConfig() {
  142. return config;
  143. }
  144.  
  145. public List<File> getDomainConfig() {
  146. return domainConfig;
  147. }
  148.  
  149. @Override
  150. public CommandResult execute(CommandInvocation commandInvocation) {
  151. if(help)
  152. commandInvocation.getShell().out().println(commandInvocation.getHelpInfo("monitor"));
  153. else {
  154. this.shell = commandInvocation.getShell();
  155. attached = true;
  156. commandInvocation.attachConsoleCommand(this);
  157.  
  158. initClient(commandInvocation);
  159.  
  160. setupMonitoring();
  161.  
  162. startMonitoring();
  163.  
  164. }
  165.  
  166. return CommandResult.SUCCESS;
  167. }
  168.  
  169. private void connectWithPassword() {
  170. client = NativeClient.getInstance(host, port, username, password);
  171. }
  172.  
  173. private void setupMonitoring() {
  174. // Setup for monitoring the specified subsystems and/or deployments
  175. if(serverConfiguration != null)
  176. monitors = serverConfiguration.createMonitors(client, subsystems, deployments, deploymentSubsystems);
  177. else
  178. shell.out().println("ServerConfiguration is null, cannot start monitors");
  179. }
  180.  
  181. private void initClient(CommandInvocation ci) {
  182. // Try connecting to the server without authentication first
  183.  
  184. ModelControllerClient unauthenticatedClient = NativeClient.getInstance(host, port);
  185.  
  186. if (NativeClient.needsToAuthenticate(unauthenticatedClient)) {
  187. // Failed to connect, must authenticate
  188.  
  189. if (username == null && password == null) {
  190.  
  191. ci.getShell().out().println("Connection failed, so you must authenticate!");
  192. ci.getShell().out().print("Enter username: ");
  193. ci.getShell().out().flush();
  194. status = Status.USERNAME;
  195.  
  196. }
  197. try {
  198. unauthenticatedClient.close();
  199. } catch (IOException e) {
  200. logger.info("Tried to close the unauthenticated client, because we needed to authenticate, but it failed!");
  201. }
  202. }
  203. else {
  204. client = unauthenticatedClient;
  205. }
  206. }
  207.  
  208. private void startMonitoring() {
  209. MonitorResourcesRunner runner = new MonitorResourcesRunner(logger, monitors, client, file, interval, timestamp);
  210.  
  211. try {
  212. runner.startMonitoring();
  213. }
  214. catch (InitialiseMonitorResourcesException e) {
  215. shell.out().println("MonitorResources failed to start with the following error message: "+e.getMessage());
  216. }
  217. }
  218.  
  219. public void shutdown() {
  220. if(client != null)
  221. try {
  222. client.close();
  223. } catch (IOException e) {
  224. e.printStackTrace();
  225. }
  226. }
  227.  
  228. private void setServerConfiguration(ServerConfiguration serverConfiguration) {
  229. this.serverConfiguration = serverConfiguration;
  230. }
  231.  
  232. @Override
  233. public void processOperation(CommandOperation commandOperation) throws IOException {
  234. if(status == Status.DEFAULT) {
  235.  
  236. }
  237. else if(status == Status.USERNAME) {
  238. if(commandOperation.getInputKey() == Key.ENTER) {
  239. status = Status.PASSWORD;
  240. shell.out().print("Enter password: ");
  241. shell.out().flush();
  242. }
  243. else
  244. username = username + commandOperation.getInputKey().getAsChar();
  245. }
  246. else if(status == Status.PASSWORD) {
  247. if(commandOperation.getInputKey() == Key.ENTER) {
  248.  
  249. connectWithPassword();
  250. status = Status.PASSWORD;
  251. }
  252. else
  253. password = password + commandOperation.getInputKey().getAsChar();
  254. }
  255. }
  256.  
  257. @Override
  258. public boolean isAttached() {
  259. return attached;
  260. }
  261.  
  262. public static class PortValidator implements OptionValidator<Integer> {
  263. @Override
  264. public void validate(Integer port) throws OptionValidatorException {
  265. if(port < 0 || port > 65535)
  266. throw new OptionValidatorException("Hey, looks like you specified an invalid port number: "+port);
  267. }
  268. }
  269.  
  270. public static class InetConverter implements CLConverter<InetAddress> {
  271. @Override
  272. public InetAddress convert(String host) throws OptionValidatorException {
  273. try {
  274. return InetAddress.getByName(host);
  275. }
  276. catch (UnknownHostException e) {
  277. throw new OptionValidatorException("Hey, looks like the host is invalid: " + e.getMessage());
  278. }
  279. }
  280. }
  281.  
  282. public static class JarFileConverter implements CLConverter<JarFile> {
  283.  
  284. @Override
  285. public JarFile convert(String deployment) throws OptionValidatorException {
  286. try {
  287. return new JarFile(deployment);
  288. }
  289. catch (IOException e) {
  290. throw new OptionValidatorException(
  291. "The deployment file you specified was invalid: "+e.getMessage());
  292. }
  293. }
  294. }
  295.  
  296. public static class PrintWriterConverter implements CLConverter<PrintWriter> {
  297. @Override
  298. public PrintWriter convert(String file) throws OptionValidatorException {
  299. try {
  300. return new PrintWriter(new File(file));
  301. }
  302. catch (IOException e) {
  303. throw new OptionValidatorException("Could not open file: "+file+", "+e.getMessage());
  304. }
  305. }
  306. }
  307.  
  308. public static class DeploymentSubsystemsValidator implements OptionValidator<String> {
  309.  
  310. @Override
  311. public void validate(String value) throws OptionValidatorException {
  312. for(String subsystem : deploymentSubsystemValues)
  313. if(subsystem.equals(value))
  314. return;
  315.  
  316. throw new OptionValidatorException("Value "+value+" is not accepted, must one of: "+ Arrays.toString(deploymentSubsystemValues));
  317. }
  318. }
  319.  
  320. public static class SubsystemsValidator implements OptionValidator<String> {
  321.  
  322. @Override
  323. public void validate(String value) throws OptionValidatorException {
  324. for(String subsystem : subsystemValues)
  325. if(subsystem.equals(value))
  326. return;
  327.  
  328. throw new OptionValidatorException("Value "+value+" is not accepted, must one of: "+ Arrays.toString(deploymentSubsystemValues));
  329. }
  330. }
  331.  
  332. public class MonitorValidator implements CommandValidator<MonitorResourcesCommand> {
  333.  
  334. @Override
  335. public void validate(MonitorResourcesCommand command) throws CommandValidatorException {
  336.  
  337. if(command.getConfig() == null || !command.getConfig().isFile()) {
  338. if(command.getDomainConfig() == null || command.getDomainConfig().size() == 0)
  339. throw new CommandValidatorException("You did not specify a server configuration file (either domain or standalone) to parse for subsystem information!");
  340. if(command.getDomainConfig().size() != 2)
  341. throw new CommandValidatorException("You did not specify the correct number of arguments for domain-config option. You should specify two files, the host and domain xml files.");
  342. }
  343.  
  344. if(command.getSubsystems() == null || command.getSubsystems().size() == 0) {
  345. command.subsystems = ServerConfiguration.subsystemsToMonitor();
  346. }
  347. else {
  348. if (command.subsystems.size() == 1 && (command.subsystems.get(0).equals("all"))) {
  349. command.subsystems = ServerConfiguration.subsystemsToMonitor();
  350. }
  351. else if (command.subsystems.size() == 1 && (command.subsystems.get(0).equals("none"))) {
  352. command.subsystems = null;
  353. }
  354. else {
  355. boolean subsystemsAreValid = false;
  356. List<String> possibleSubsystemsToMonitor = ServerConfiguration.subsystemsToMonitor();
  357. if (possibleSubsystemsToMonitor.containsAll(command.subsystems)) {
  358. subsystemsAreValid = true;
  359. }
  360. if (!subsystemsAreValid) {
  361. throw new CommandValidatorException(
  362. "The subsystems you specified on the command line are not completely valid." +
  363. "Valid subsystems are " + ServerConfiguration.subsystemsToMonitor() + " or all or none.");
  364. }
  365. }
  366. }
  367.  
  368. if(command.getDeployments() != null) {
  369. command.deploymentsToMonitor = true;
  370. // So we are doing deployment monitoring, so let's see if the deployment-subsystems are valid
  371. if (command.deploymentSubsystems == null) {
  372. command.deploymentSubsystems = ServerConfiguration.deploymentSubsystemsToMonitor();
  373. }
  374. else {
  375. if (command.deploymentSubsystems.size() == 1 &&
  376. (command.deploymentSubsystems.get(0).equals("all"))) {
  377. command.deploymentSubsystems = ServerConfiguration.deploymentSubsystemsToMonitor();
  378. }
  379. else if (command.deploymentSubsystems.size() == 1 &&
  380. (command.deploymentSubsystems.get(0).equals("none"))) {
  381. if (command.subsystems == null) {
  382. // Specified no monitoring at all, with none on subsystems, and none on deployment subsystems
  383. throw new CommandValidatorException(
  384. "You must specify a subsystem to monitor either for general subsystems, or deployment specific subsystems, but both were specified as none." +
  385. "Valid subsystems are " + ServerConfiguration.subsystemsToMonitor() +
  386. "Valid deloyment-subsystems are " + ServerConfiguration.deploymentSubsystemsToMonitor());
  387. }
  388. command.deploymentSubsystems = null;
  389. }
  390. else {
  391. boolean deploymentSubsystemsAreValid = false;
  392. List<String> possibleDeploymentSubsystemsToMonitor = ServerConfiguration.deploymentSubsystemsToMonitor();
  393. if (possibleDeploymentSubsystemsToMonitor.containsAll(command.deploymentSubsystems)) {
  394. deploymentSubsystemsAreValid = true;
  395. }
  396. if (!deploymentSubsystemsAreValid) {
  397. throw new CommandValidatorException(
  398. "The deployment-subsystems you specified on the command line are not completely valid." +
  399. "Valid deployment-subsystems are " + ServerConfiguration.deploymentSubsystemsToMonitor() + "or all or none.");
  400. }
  401. }
  402. }
  403. }
  404.  
  405. parseServerConfigFile(command);
  406.  
  407. }
  408.  
  409. private void parseServerConfigFile(MonitorResourcesCommand command) throws CommandValidatorException {
  410. // Parse the servers configuration file
  411. SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
  412. ServerConfiguration serverConfiguration = null;
  413.  
  414. serverConfiguration = ServerConfigurationFactory.createServerConfiguration(
  415. command.domainMode, command.deploymentsToMonitor, command.deployments);
  416.  
  417. try {
  418. SAXParser saxParser = saxParserFactory.newSAXParser();
  419.  
  420. if (command.domainMode) {
  421. saxParser.parse(command.domainConfig.get(0), serverConfiguration);
  422. saxParser.parse(command.domainConfig.get(1), serverConfiguration);
  423. }
  424. else {
  425. saxParser.parse(command.config, serverConfiguration);
  426. }
  427. }
  428. catch (SAXException e) {
  429. throw new CommandValidatorException("Configuration file may not be valid: "+e.getMessage());
  430. }
  431. catch (ParserConfigurationException e) {
  432. throw new CommandValidatorException("Parser configuration error: "+e.getMessage());
  433. }
  434. catch (IOException e) {
  435. throw new CommandValidatorException("Looks like the file name may not be correct: "+e.getMessage());
  436. }
  437.  
  438. // Check if the host and port passed on the command line - or the defaults, match the configuration file
  439. if (!serverConfiguration.getManagementInterfaceHostName().equalsIgnoreCase(command.host.getHostName()) &&
  440. !serverConfiguration.getManagementInterfaceHostName().equalsIgnoreCase(command.host.getHostAddress())) {
  441. throw new CommandValidatorException(
  442. "Specified and/or default host does not match the host specified in the configuration file!" +
  443. "Specified and/or default host is : " + command.host +
  444. "Host in the configuration file is: " + serverConfiguration.getManagementInterfaceHostName());
  445. }
  446.  
  447. if (serverConfiguration.getManagementInterfacePort() != command.port) {
  448. throw new CommandValidatorException(
  449. "Specified and/or default port does not match the port specified in the configuration file!" +
  450. "Specified and/or default port is : " + command.port +
  451. "Port in the configuration file is: " + serverConfiguration.getManagementInterfacePort());
  452. }
  453.  
  454. //todo: this doesnt do much atm, serverNames is not used
  455. if (command.domainMode) {
  456. List<String> serverNames;
  457. if (command.domainServerNames == null) {
  458. serverNames = serverConfiguration.getServerNames();
  459. } else {
  460. serverNames = command.domainServerNames;
  461. if (serverNames.size() == 1 && (serverNames.get(0).equals("all"))) {
  462. serverNames = serverConfiguration.getServerNames();
  463. } else {
  464. boolean serverNamesAreValid = false;
  465. List<String> possibleServerNames = serverConfiguration.getServerNames();
  466. if (possibleServerNames.containsAll(serverNames)) {
  467. serverNamesAreValid = true;
  468. }
  469. if (!serverNamesAreValid) {
  470. throw new CommandValidatorException(
  471. "The server names you specified on the command line are not valid." +
  472. "Valid server names from your configuration are " + serverConfiguration.getServerNames() + " or all");
  473. }
  474. }
  475. }
  476. }
  477.  
  478. // Check to see that the XML configuration contained information for address for all the subsystems specified for monitoring
  479. if (command.subsystems != null) {
  480. List<String> removedSubsystems = new ArrayList<String>();
  481.  
  482. for (String subsystem : command.subsystems) {
  483. if (!serverConfiguration.subsystemHasAddressInConfiguration(subsystem)) {
  484. logger.warn("Missing configuration needed for monitoring of subsystem " + subsystem + "!");
  485. logger.warn("Removing " + subsystem + " from monitoring.");
  486. removedSubsystems.add(subsystem);
  487. }
  488. }
  489.  
  490. command.subsystems.removeAll(removedSubsystems);
  491.  
  492. if (command.subsystems.isEmpty()) {
  493. throw new CommandValidatorException(
  494. "Due to previous warnings, there are no valid subsystems to monitor!" +
  495. "Exiting due to previous errors. You will need to configure your server correctly for monitoring.");
  496. }
  497. }
  498.  
  499. command.setServerConfiguration(serverConfiguration);
  500. }
  501.  
  502. }
  503.  
  504. enum Status {
  505. USERNAME,
  506. PASSWORD,
  507. DEFAULT;
  508. }
  509. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement