@Override public void run() { LocalProcessController stopper = null; try { stopper = new LocalProcessController(pid); stopper.connect(); assertTrue(stopper.checkPidMatches()); } catch (ConnectionFailedException e) { throw new Error(e); } catch (IOException e) { throw new Error(e); } catch (IllegalStateException e) { throw new Error(e); } catch (PidUnavailableException e) { throw new Error(e); } finally { if (stopper != null) { stopper.disconnect(); } } } });
/** * Connects to the process and tells it to shut down. * * @param namePattern the name pattern of the MBean to use for stopping * @param pidAttribute the name of the MBean attribute with the process id to compare against * @param stopMethod the name of the MBean operation to invoke * @param attributes the names of the MBean attributes to compare with expected values * @param values the expected values of the specified MBean attributes * * @throws ConnectionFailedException if there was a failure to connect to the local JMX connector in the process * @throws IOException if a communication problem occurred when talking to the MBean server * @throws MBeanInvocationFailedException if failed to invoke stop on the MBean for any reason * @throws PidUnavailableException if parsing the pid from the RuntimeMXBean name fails */ public void stop(final ObjectName namePattern, final String pidAttribute, final String stopMethod, final String[] attributes, final Object[] values) throws ConnectionFailedException, IOException, MBeanInvocationFailedException, PidUnavailableException { invokeOperationOnTargetMBean(namePattern, pidAttribute, stopMethod, attributes, values); }
/** * Constructs an instance for controlling a local process. * * @param pidFile file containing the pid of the process to attach to * * @throws FileNotFoundException if the specified file name is not found within the directory * @throws IOException if unable to read from the specified file * @throws IllegalArgumentException if the pid in the pidFile is not a positive integer * @throws NumberFormatException if the pid file does not contain a parsable integer */ public LocalProcessController(final File pidFile) throws IOException { this(readPid(pidFile)); }
throws ConnectionFailedException, IOException, MBeanInvocationFailedException, PidUnavailableException { ObjectName objectName = namePattern; connect(); try { final QueryExp constraint = buildQueryExp(pidAttribute, attributes, values); final Set<ObjectName> mbeanNames = this.server.queryNames(namePattern, constraint); return invoke(objectName, methodName); } catch (InstanceNotFoundException e) { throw new MBeanInvocationFailedException("Failed to invoke " + methodName + " on " + objectName, e); throw new MBeanInvocationFailedException("Failed to invoke " + methodName + " on " + objectName, e); } finally { disconnect();
/** * Connects to the JMX agent in the local process. * * @throws ConnectionFailedException if there was a failure to connect to the local JMX connector in the process * @throws IOException if the JDK management agent cannot be found and loaded */ void connect() throws ConnectionFailedException, IOException { try { final JMXServiceURL jmxUrl = getJMXServiceURL(); this.jmxc = JMXConnectorFactory.connect(jmxUrl); this.server = this.jmxc.getMBeanServerConnection(); } catch (AttachNotSupportedException e) { throw new ConnectionFailedException("Failed to connect to process '" + this.pid + "'", e); } }
/** * Builds the QueryExp used to identify the target MBean. * * @param pidAttribute the name of the MBean attribute with the process id to compare against * @param attributes the names of additional MBean attributes to compare with expected values * @param values the expected values of the specified MBean attributes * * @return the main QueryExp for matching the target MBean */ private QueryExp buildQueryExp(final String pidAttribute, final String[] attributes, final Object[] values) { final QueryExp optionalAttributes = buildOptionalQueryExp(attributes, values); QueryExp constraint; if (optionalAttributes != null) { constraint = Query.and(optionalAttributes, Query.eq( Query.attr(pidAttribute), Query.value(this.pid))); } else { constraint = Query.eq( Query.attr(pidAttribute), Query.value(this.pid)); } return constraint; }
public void testConnectPidMatchesDisconnect() throws Exception { final int pid = ProcessUtils.identifyPid(); Host.getHost(0).getVM(0).invoke(new SerializableRunnable("LocalProcessControllerDUnitTest#testConnectPidMatchesDisconnect") { @Override public void run() { LocalProcessController stopper = null; try { stopper = new LocalProcessController(pid); stopper.connect(); assertTrue(stopper.checkPidMatches()); } catch (ConnectionFailedException e) { throw new Error(e); } catch (IOException e) { throw new Error(e); } catch (IllegalStateException e) { throw new Error(e); } catch (PidUnavailableException e) { throw new Error(e); } finally { if (stopper != null) { stopper.disconnect(); } } } }); }
throws ConnectionFailedException, IOException, MBeanInvocationFailedException, PidUnavailableException { ObjectName objectName = namePattern; connect(); try { final QueryExp constraint = buildQueryExp(pidAttribute, attributes, values); final Set<ObjectName> mbeanNames = this.server.queryNames(namePattern, constraint); return invoke(objectName, methodName); } catch (InstanceNotFoundException e) { throw new MBeanInvocationFailedException("Failed to invoke " + methodName + " on " + objectName, e); throw new MBeanInvocationFailedException("Failed to invoke " + methodName + " on " + objectName, e); } finally { disconnect();
/** * Connects to the JMX agent in the local process. * * @throws ConnectionFailedException if there was a failure to connect to the local JMX connector in the process * @throws IOException if the JDK management agent cannot be found and loaded */ void connect() throws ConnectionFailedException, IOException { try { final JMXServiceURL jmxUrl = getJMXServiceURL(); this.jmxc = JMXConnectorFactory.connect(jmxUrl); this.server = this.jmxc.getMBeanServerConnection(); } catch (AttachNotSupportedException e) { throw new ConnectionFailedException("Failed to connect to process '" + this.pid + "'", e); } }
/** * Builds the QueryExp used to identify the target MBean. * * @param pidAttribute the name of the MBean attribute with the process id to compare against * @param attributes the names of additional MBean attributes to compare with expected values * @param values the expected values of the specified MBean attributes * * @return the main QueryExp for matching the target MBean */ private QueryExp buildQueryExp(final String pidAttribute, final String[] attributes, final Object[] values) { final QueryExp optionalAttributes = buildOptionalQueryExp(attributes, values); QueryExp constraint; if (optionalAttributes != null) { constraint = Query.and(optionalAttributes, Query.eq( Query.attr(pidAttribute), Query.value(this.pid))); } else { constraint = Query.eq( Query.attr(pidAttribute), Query.value(this.pid)); } return constraint; }
public void testStartAndStopProcess() throws Exception { final String testName = "testStartAndStopProcess"; execAndValidate(new String[] { ""+this.registryPort, testName }, TEST_CASE + " process running"); final File pidFile = new File(TEST_CASE + File.separator + testName + ".pid"); final ObjectName objectName = ObjectName.getInstance( TEST_CASE + ":testName=" + testName); final String pidAttribute = "Pid"; final String method = "stop"; final LocalProcessController stopper = new LocalProcessController(pidFile); stopper.connect(); assertTrue(stopper.checkPidMatches()); stopper.disconnect(); stopper.stop(objectName, pidAttribute, method, new String[] {"Process"}, new Object[]{Boolean.TRUE}); }
/** * Constructs an instance for controlling a local process. * * @param pidFile file containing the pid of the process to attach to * * @throws FileNotFoundException if the specified file name is not found within the directory * @throws IOException if unable to read from the specified file * @throws IllegalArgumentException if the pid in the pidFile is not a positive integer * @throws NumberFormatException if the pid file does not contain a parsable integer */ public LocalProcessController(final File pidFile) throws IOException { this(readPid(pidFile)); }
/** * Connects to the process and tells it to shut down. * * @param namePattern the name pattern of the MBean to use for stopping * @param pidAttribute the name of the MBean attribute with the process id to compare against * @param stopMethod the name of the MBean operation to invoke * @param attributes the names of the MBean attributes to compare with expected values * @param values the expected values of the specified MBean attributes * * @throws ConnectionFailedException if there was a failure to connect to the local JMX connector in the process * @throws IOException if a communication problem occurred when talking to the MBean server * @throws MBeanInvocationFailedException if failed to invoke stop on the MBean for any reason * @throws PidUnavailableException if parsing the pid from the RuntimeMXBean name fails */ public void stop(final ObjectName namePattern, final String pidAttribute, final String stopMethod, final String[] attributes, final Object[] values) throws ConnectionFailedException, IOException, MBeanInvocationFailedException, PidUnavailableException { invokeOperationOnTargetMBean(namePattern, pidAttribute, stopMethod, attributes, values); }
/** * Constructs an instance for controlling a local process. * * @param directory directory containing a file of name pidFileName * @param pidFilename name of the file containing the pid of the process to attach to * * @throws FileNotFoundException if the specified file name is not found within the directory * @throws IOException if an I/O error occurs * @throws IllegalArgumentException if the pid in the pidFile is not a positive integer * @throws IllegalStateException if dir is not an existing directory * @throws NumberFormatException if the pid file does not contain a parsable integer */ public LocalProcessController(final File directory, final String pidFilename) throws IOException { this(readPid(directory, pidFilename)); }
/** * Connects to the process and acquires its status. * * @param namePattern the name pattern of the MBean to use for stopping * @param pidAttribute the name of the MBean attribute with the process id to compare against * @param statusMethod the name of the MBean operation to invoke * @param attributes the names of the MBean attributes to compare with expected values * @param values the expected values of the specified MBean attributes * * @return string describing the status of the process * * @throws ConnectionFailedException if there was a failure to connect to the local JMX connector in the process * @throws IOException if a communication problem occurred when talking to the MBean server * @throws MBeanInvocationFailedException if failed to invoke stop on the MBean for any reason * @throws PidUnavailableException if parsing the pid from the RuntimeMXBean name fails */ public String status(final ObjectName namePattern, final String pidAttribute, final String statusMethod, final String[] attributes, final Object[] values) throws ConnectionFailedException, IOException, MBeanInvocationFailedException, PidUnavailableException { return invokeOperationOnTargetMBean(namePattern, pidAttribute, statusMethod, attributes, values).toString(); }
/** * Constructs an instance for controlling a local process. * * @param directory directory containing a file of name pidFileName * @param pidFilename name of the file containing the pid of the process to attach to * * @throws FileNotFoundException if the specified file name is not found within the directory * @throws IOException if an I/O error occurs * @throws IllegalArgumentException if the pid in the pidFile is not a positive integer * @throws IllegalStateException if dir is not an existing directory * @throws NumberFormatException if the pid file does not contain a parsable integer */ public LocalProcessController(final File directory, final String pidFilename) throws IOException { this(readPid(directory, pidFilename)); }
/** * Connects to the process and acquires its status. * * @param namePattern the name pattern of the MBean to use for stopping * @param pidAttribute the name of the MBean attribute with the process id to compare against * @param statusMethod the name of the MBean operation to invoke * @param attributes the names of the MBean attributes to compare with expected values * @param values the expected values of the specified MBean attributes * * @return string describing the status of the process * * @throws ConnectionFailedException if there was a failure to connect to the local JMX connector in the process * @throws IOException if a communication problem occurred when talking to the MBean server * @throws MBeanInvocationFailedException if failed to invoke stop on the MBean for any reason * @throws PidUnavailableException if parsing the pid from the RuntimeMXBean name fails */ public String status(final ObjectName namePattern, final String pidAttribute, final String statusMethod, final String[] attributes, final Object[] values) throws ConnectionFailedException, IOException, MBeanInvocationFailedException, PidUnavailableException { return invokeOperationOnTargetMBean(namePattern, pidAttribute, statusMethod, attributes, values).toString(); }
/** * Reads in the pid from the named file contained within the specified * directory. * * @param directory directory containing a file of name pidFileName * @param pidFilename name of the file containing the pid of the process to stop * * @return the process id (pid) contained within the pidFile * * @throws FileNotFoundException if the specified file name is not found within the directory * @throws IllegalArgumentException if the pid in the pidFile is not a positive integer * @throws IllegalStateException if dir is not an existing directory * @throws IOException if an I/O error occurs * @throws NumberFormatException if the pid file does not contain a parsable integer */ private static int readPid(final File directory, final String pidFilename) throws IOException { if (!directory.isDirectory() && directory.exists()) { throw new IllegalArgumentException("Argument '" + directory + "' must be an existing directory!"); } final File[] files = directory.listFiles(new FilenameFilter() { @Override public boolean accept(File file, String filename) { return filename.equals(pidFilename); } }); if (files.length == 0) { throw new FileNotFoundException("Unable to find PID file '" + pidFilename + "' in directory " + directory); } return readPid(files[0]); }
/** * Reads in the pid from the named file contained within the specified * directory. * * @param directory directory containing a file of name pidFileName * @param pidFilename name of the file containing the pid of the process to stop * * @return the process id (pid) contained within the pidFile * * @throws FileNotFoundException if the specified file name is not found within the directory * @throws IllegalArgumentException if the pid in the pidFile is not a positive integer * @throws IllegalStateException if dir is not an existing directory * @throws IOException if an I/O error occurs * @throws NumberFormatException if the pid file does not contain a parsable integer */ private static int readPid(final File directory, final String pidFilename) throws IOException { if (!directory.isDirectory() && directory.exists()) { throw new IllegalArgumentException("Argument '" + directory + "' must be an existing directory!"); } final File[] files = directory.listFiles(new FilenameFilter() { @Override public boolean accept(File file, String filename) { return filename.equals(pidFilename); } }); if (files.length == 0) { throw new FileNotFoundException("Unable to find PID file '" + pidFilename + "' in directory " + directory); } return readPid(files[0]); }