Mercurial > hg > release > thermostat-0.4
changeset 580:c95cd9ae6db4
Remote kill-vm.
This patch implements kill-vm via command channel. Similar to the heap dumper
bundle there are now killvm agent/client bundles. Tests have been added where
appropriate. Previously there were none :( Also added proper localization.
PR1144
Reviewed-by: neugens
Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2012-August/003006.html
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/agent/killvm/pom.xml Thu Aug 30 17:37:39 2012 +0200 @@ -0,0 +1,120 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + Copyright 2012 Red Hat, Inc. + + This file is part of Thermostat. + + Thermostat is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 2, or (at your + option) any later version. + + Thermostat is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Thermostat; see the file COPYING. If not see + <http://www.gnu.org/licenses />. + + Linking this code with other modules is making a combined work + based on this code. Thus, the terms and conditions of the GNU + General Public License cover the whole combination. + + As a special exception, the copyright holders of this code give + you permission to link this code with independent modules to + produce an executable, regardless of the license terms of these + independent modules, and to copy and distribute the resulting + executable under terms of your choice, provided that you also + meet, for each linked independent module, the terms and conditions + of the license of that module. An independent module is a module + which is not derived from or based on this code. If you modify + this code, you may extend this exception to your version of the + library, but you are not obligated to do so. If you do not wish + to do so, delete this exception statement from your version. + +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-agent</artifactId> + <version>0.4.0-SNAPSHOT</version> + </parent> + + <artifactId>thermostat-agent-killvm</artifactId> + <packaging>bundle</packaging> + + <name>Thermostat Agent Kill VM</name> + + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.powermock</groupId> + <artifactId>powermock-api-mockito</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.powermock</groupId> + <artifactId>powermock-module-junit4</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-agent-core</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-agent-command</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-common-core</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-launcher</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.core</artifactId> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Bundle-Vendor>Red Hat, Inc.</Bundle-Vendor> + <Bundle-Activator>com.redhat.thermostat.agent.killvm.internal.Activator</Bundle-Activator> + <Bundle-SymbolicName>com.redhat.thermostat.agent.killvm</Bundle-SymbolicName> + <Private-Package>com.redhat.thermostat.agent.killvm.internal</Private-Package> + <!-- Do not autogenerate uses clauses in Manifests --> + <_nouses>true</_nouses> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + +</project> \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/agent/killvm/src/main/java/com/redhat/thermostat/agent/killvm/internal/Activator.java Thu Aug 30 17:37:39 2012 +0200 @@ -0,0 +1,64 @@ +/* + * Copyright 2012 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.agent.killvm.internal; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +import com.redhat.thermostat.agent.command.ReceiverRegistry; +import com.redhat.thermostat.common.utils.OSGIUtils; +import com.redhat.thermostat.service.process.UNIXProcessHandler; + +public class Activator implements BundleActivator { + + private ReceiverRegistry registry; + private UNIXProcessHandler unixService; + + @Override + public void start(final BundleContext context) throws Exception { + unixService = OSGIUtils.getInstance().getService(UNIXProcessHandler.class); + registry = new ReceiverRegistry(context); + registry.registerReceiver(new KillVmReceiver(unixService)); + } + + @Override + public void stop(BundleContext context) throws Exception { + // This only unregisters receivers which we've registered + // in start() + registry.unregisterReceivers(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/agent/killvm/src/main/java/com/redhat/thermostat/agent/killvm/internal/KillVmReceiver.java Thu Aug 30 17:37:39 2012 +0200 @@ -0,0 +1,70 @@ +/* + * Copyright 2012 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.agent.killvm.internal; + +import java.util.logging.Logger; + +import com.redhat.thermostat.agent.command.RequestReceiver; +import com.redhat.thermostat.common.command.Request; +import com.redhat.thermostat.common.command.Response; +import com.redhat.thermostat.common.command.Response.ResponseType; +import com.redhat.thermostat.service.process.UNIXProcessHandler; +import com.redhat.thermostat.service.process.UNIXSignal; + +public class KillVmReceiver implements RequestReceiver { + + private final UNIXProcessHandler unixService; + private static final Logger log = Logger.getLogger(KillVmReceiver.class.getName()); + + public KillVmReceiver(UNIXProcessHandler unixService) { + this.unixService = unixService; + } + + @Override + public Response receive(Request request) { + if (unixService == null) { + // no dice, should have service by now + log.severe("Unix service null!"); + return new Response(ResponseType.ERROR); + } + String vmId = request.getParameter("vm-id"); + unixService.sendSignal(vmId, UNIXSignal.TERM); + log.fine("Killed VM with ID " + vmId); + return new Response(ResponseType.OK); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/agent/killvm/src/test/java/com/redhat/thermostat/agent/killvm/internal/ActivatorTest.java Thu Aug 30 17:37:39 2012 +0200 @@ -0,0 +1,87 @@ +/* + * Copyright 2012 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.agent.killvm.internal; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.eq; +import static org.mockito.Matchers.isA; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.Dictionary; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceRegistration; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import com.redhat.thermostat.agent.command.RequestReceiver; +import com.redhat.thermostat.common.utils.OSGIUtils; +import com.redhat.thermostat.service.process.UNIXProcessHandler; + +@RunWith(PowerMockRunner.class) +@PrepareForTest(OSGIUtils.class) +public class ActivatorTest { + + /** + * Makes sure receiver is registered and unix service gets set. + * + * @throws Exception + */ + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Test + public void startStopTest() throws Exception { + OSGIUtils utils = mock(OSGIUtils.class); + PowerMockito.mockStatic(OSGIUtils.class); + when(OSGIUtils.getInstance()).thenReturn(utils); + BundleContext ctx = mock(BundleContext.class); + ServiceRegistration serviceReg = mock(ServiceRegistration.class); + when(ctx.registerService(anyString(), any(), any(Dictionary.class))).thenReturn(serviceReg); + Activator activator = new Activator(); + activator.start(ctx); + verify(utils).getService(UNIXProcessHandler.class); + verify(ctx).registerService(eq(RequestReceiver.class.getName()), isA(KillVmReceiver.class), any(Dictionary.class)); + activator.stop(ctx); + verify(serviceReg).unregister(); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/agent/killvm/src/test/java/com/redhat/thermostat/agent/killvm/internal/KillVmReceiverTest.java Thu Aug 30 17:37:39 2012 +0200 @@ -0,0 +1,102 @@ +/* + * Copyright 2012 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.agent.killvm.internal; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.mock; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; + +import org.junit.Test; + +import com.redhat.thermostat.common.command.Request; +import com.redhat.thermostat.common.command.Response; +import com.redhat.thermostat.common.command.Response.ResponseType; +import com.redhat.thermostat.service.process.UNIXProcessHandler; + +public class KillVmReceiverTest { + + @Test + public void receiverReturnsOk() { + UNIXProcessHandler proc = mock(UNIXProcessHandler.class); + KillVmReceiver receiver = new KillVmReceiver(proc); + Request req = mock(Request.class); + Response response = receiver.receive(req); + assertEquals(ResponseType.OK, response.getType()); + } + + @Test + public void receiverReturnsError() { + KillVmReceiver receiver = new KillVmReceiver(null); + Request req = mock(Request.class); + Response response = receiver.receive(req); + assertEquals(ResponseType.ERROR, response.getType()); + } + + /** + * When a request is issued the fully qualified receiver class name is set + * via {@link Request#setReceiver(String)}. This test makes sure that this + * class is actually where it's supposed to be. + * + * @throws Exception + */ + @Test + public void killVmReceiverIsInAppropriatePackage() { + Class<?> receiver = null; + try { + // com.redhat.thermostat.client.killvm.internal.KillVMAction uses + // this class name. + receiver = Class + .forName("com.redhat.thermostat.agent.killvm.internal.KillVmReceiver"); + } catch (ClassNotFoundException e) { + fail("com.redhat.thermostat.agent.killvm.internal.KillVmReceiver class not found, but used by some request!"); + } + try { + Constructor<?> constructor = receiver.getConstructor(UNIXProcessHandler.class); + UNIXProcessHandler service = mock(UNIXProcessHandler.class); + Object instance = constructor.newInstance(service); + Method m = receiver.getMethod("receive", Request.class); + Request req = mock(Request.class); + m.invoke(instance, req); + } catch (Exception e) { + e.printStackTrace(); + fail("cannot invoke receiver's receive method"); + } + } +}
--- a/agent/pom.xml Fri Aug 31 17:49:45 2012 +0200 +++ b/agent/pom.xml Thu Aug 30 17:37:39 2012 +0200 @@ -63,6 +63,7 @@ <module>core</module> <module>command</module> <module>heapdumper</module> + <module>killvm</module> </modules> </project>
--- a/client/killvm/pom.xml Fri Aug 31 17:49:45 2012 +0200 +++ b/client/killvm/pom.xml Thu Aug 30 17:37:39 2012 +0200 @@ -18,9 +18,10 @@ <configuration> <instructions> <Bundle-Vendor>Red Hat, Inc.</Bundle-Vendor> - <Bundle-Activator>com.redhat.thermostat.client.killvm.Activator</Bundle-Activator> + <Bundle-Activator>com.redhat.thermostat.client.killvm.internal.Activator</Bundle-Activator> <Bundle-SymbolicName>com.redhat.thermostat.client.killvm</Bundle-SymbolicName> - <Private-Package>com.redhat.thermostat.client.killvm</Private-Package> + <Export-Package>com.redhat.thermostat.client.killvm.locale</Export-Package> + <Private-Package>com.redhat.thermostat.client.killvm.internal</Private-Package> </instructions> <!-- Do not autogenerate uses clauses in Manifests --> <_nouses>true</_nouses> @@ -40,6 +41,16 @@ <scope>test</scope> </dependency> <dependency> + <groupId>org.powermock</groupId> + <artifactId>powermock-api-mockito</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.powermock</groupId> + <artifactId>powermock-module-junit4</artifactId> + <scope>test</scope> + </dependency> + <dependency> <groupId>org.easytesting</groupId> <artifactId>fest-swing</artifactId> <scope>test</scope> @@ -70,6 +81,16 @@ <version>${project.version}</version> </dependency> <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-client-command</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-common-command</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> <groupId>com.redhat.thermostat</groupId> <artifactId>thermostat-osgi-process-handler</artifactId> <version>${project.version}</version>
--- a/client/killvm/src/main/java/com/redhat/thermostat/client/killvm/Activator.java Fri Aug 31 17:49:45 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,119 +0,0 @@ -/* - * Copyright 2012 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <http://www.gnu.org/licenses/>. - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.client.killvm; - -import java.util.logging.Level; -import java.util.logging.Logger; - -import org.osgi.framework.BundleActivator; -import org.osgi.framework.BundleContext; -import org.osgi.framework.ServiceEvent; -import org.osgi.framework.ServiceListener; -import org.osgi.framework.ServiceReference; - -import com.redhat.thermostat.client.osgi.service.ApplicationService; -import com.redhat.thermostat.client.osgi.service.ContextAction; -import com.redhat.thermostat.client.osgi.service.VMContextAction; -import com.redhat.thermostat.service.process.UNIXProcessHandler; - -public class Activator implements BundleActivator { - - private static final Logger logger = Logger.getLogger(Activator.class.getSimpleName()); - - @Override - public void start(final BundleContext context) throws Exception { - - // FIXME: there should be a better way than this - // also, we need to be prepared that the unix service may disappear... - ServiceListener listener = new ServiceListener() { - - private UNIXProcessHandler unixService; - private ApplicationService appService; - private boolean[] loaded = new boolean[3]; - - @Override - public void serviceChanged(ServiceEvent event) { - - ServiceReference reference = event.getServiceReference(); - Object service = context.getService(reference); - switch (event.getType()) { - case ServiceEvent.REGISTERED: - if (service instanceof ContextAction) { - loaded[0] = true; - } else if (service instanceof UNIXProcessHandler) { - loaded[1] = true; - unixService = (UNIXProcessHandler) service; - } else if (service instanceof ApplicationService) { - loaded[2] = true; - appService = (ApplicationService) service; - } - break; - - default: - break; - } - - if (loaded[0] && loaded[1] && loaded[2]) { - context.registerService(VMContextAction.class.getName(), - new KillVMAction(unixService, appService.getDAOFactory()), null); - } - } - }; - - try { - String filter = "(|(objectClass=" + ContextAction.class.getName() + ")" + - " (objectClass=" + UNIXProcessHandler.class.getName() + ")" + - " (objectClass=" + ApplicationService.class.getName() + "))"; - - context.addServiceListener(listener, filter); - ServiceReference[] services = context.getServiceReferences(null, null); - if (services != null) { - for(int i = 0; i < services.length; i++) { - listener.serviceChanged(new ServiceEvent(ServiceEvent.REGISTERED, services[i])); - } - } - - } catch (Exception e) { - logger.log(Level.WARNING, "Failed to set up listener for http", e); - } - } - - @Override - public void stop(BundleContext context) throws Exception { - /* nothing to do here */ - } -}
--- a/client/killvm/src/main/java/com/redhat/thermostat/client/killvm/KillVMAction.java Fri Aug 31 17:49:45 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,94 +0,0 @@ -/* - * Copyright 2012 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <http://www.gnu.org/licenses/>. - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.client.killvm; - -import com.redhat.thermostat.client.osgi.service.VMContextAction; -import com.redhat.thermostat.client.osgi.service.VmFilter; -import com.redhat.thermostat.common.dao.DAOFactory; -import com.redhat.thermostat.common.dao.VmRef; -import com.redhat.thermostat.common.model.VmInfo; -import com.redhat.thermostat.service.process.UNIXProcessHandler; -import com.redhat.thermostat.service.process.UNIXSignal; - -/** - * Implements the {@link VMContextAction} entry point to provide a kill switch - * for the currently selected Virtual Machine. - */ -public class KillVMAction implements VMContextAction { - - private final UNIXProcessHandler unixService; - private final DAOFactory dao; - - public KillVMAction(UNIXProcessHandler unixService, DAOFactory dao) { - this.unixService = unixService; - this.dao = dao; - } - - @Override - public String getName() { - return "Kill Application"; - } - - @Override - public String getDescription() { - return "Kill the selected VM Process"; - } - - @Override - public void execute(VmRef reference) { - // TODO this should be executed on the agent-side - unixService.sendSignal(reference.getIdString(), UNIXSignal.TERM); - } - - @Override - public VmFilter getFilter() { - return new LocalAndAliveFilter(); - } - - private class LocalAndAliveFilter implements VmFilter { - - @Override - public boolean matches(VmRef ref) { - VmRef vm = ref; - - // TODO implement local checking too - VmInfo vmInfo = dao.getVmInfoDAO().getVmInfo(vm); - return vmInfo.isAlive(); - } - - } -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/killvm/src/main/java/com/redhat/thermostat/client/killvm/internal/Activator.java Thu Aug 30 17:37:39 2012 +0200 @@ -0,0 +1,56 @@ +/* + * Copyright 2012 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.client.killvm.internal; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +import com.redhat.thermostat.client.osgi.service.VMContextAction; + +public class Activator implements BundleActivator { + + @Override + public void start(BundleContext context) throws Exception { + context.registerService(VMContextAction.class.getName(), new KillVMAction(), null); + } + + @Override + public void stop(BundleContext context) throws Exception { + // service automatically unregistered on bundle stop + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/killvm/src/main/java/com/redhat/thermostat/client/killvm/internal/KillVMAction.java Thu Aug 30 17:37:39 2012 +0200 @@ -0,0 +1,113 @@ +/* + * Copyright 2012 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.client.killvm.internal; + +import java.net.InetSocketAddress; + +import com.redhat.thermostat.client.command.RequestQueue; +import com.redhat.thermostat.client.killvm.locale.LocaleResources; +import com.redhat.thermostat.client.osgi.service.VMContextAction; +import com.redhat.thermostat.client.osgi.service.VmFilter; +import com.redhat.thermostat.common.appctx.ApplicationContext; +import com.redhat.thermostat.common.command.Request; +import com.redhat.thermostat.common.command.Request.RequestType; +import com.redhat.thermostat.common.dao.DAOFactory; +import com.redhat.thermostat.common.dao.VmRef; +import com.redhat.thermostat.common.locale.Translate; +import com.redhat.thermostat.common.model.VmInfo; +import com.redhat.thermostat.common.utils.OSGIUtils; + +/** + * Implements the {@link VMContextAction} entry point to provide a kill switch + * for the currently selected Virtual Machine. + */ +public class KillVMAction implements VMContextAction { + + private static final String RECEIVER = "com.redhat.thermostat.agent.killvm.internal.KillVmReceiver"; + private final DAOFactory dao; + private final Translate t; + + public KillVMAction() { + this.dao = ApplicationContext.getInstance().getDAOFactory(); + this.t = LocaleResources.createLocalizer(); + } + + @Override + public String getName() { + return t.localize(LocaleResources.ACTION_NAME); + } + + @Override + public String getDescription() { + return t.localize(LocaleResources.ACTION_DESCRIPTION); + } + + @Override + public void execute(VmRef reference) { + String address = dao.getStorage().getConfigListenAddress(reference.getAgent()); + + String [] host = address.split(":"); + InetSocketAddress target = new InetSocketAddress(host[0], Integer.parseInt(host[1])); + Request murderer = getKillRequest(target); + murderer.setParameter("vm-id", reference.getIdString()); + murderer.setReceiver(RECEIVER); + murderer.addListener(new VMKilledListener()); + + RequestQueue queue = OSGIUtils.getInstance().getService(RequestQueue.class); + queue.putRequest(murderer); + } + + // testing hook; keep this package private + Request getKillRequest(InetSocketAddress target) { + return new Request(RequestType.RESPONSE_EXPECTED, target); + } + + @Override + public VmFilter getFilter() { + return new LocalAndAliveFilter(); + } + + private class LocalAndAliveFilter implements VmFilter { + + @Override + public boolean matches(VmRef ref) { + VmInfo vmInfo = dao.getVmInfoDAO().getVmInfo(ref); + return vmInfo.isAlive(); + } + + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/killvm/src/main/java/com/redhat/thermostat/client/killvm/internal/VMKilledListener.java Thu Aug 30 17:37:39 2012 +0200 @@ -0,0 +1,73 @@ +/* + * Copyright 2012 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.client.killvm.internal; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.redhat.thermostat.common.command.Request; +import com.redhat.thermostat.common.command.RequestResponseListener; +import com.redhat.thermostat.common.command.Response; + +public class VMKilledListener implements RequestResponseListener { + + private static final Logger logger = Logger.getLogger(VMKilledListener.class.getName()); + + @Override + public void fireComplete(Request request, Response response) { + switch (response.getType()) { + case NOOP: // fall-through + case EXCEPTION: // fall-through + case NOK: { + logger.log(Level.SEVERE, "Unknown response from kill VM request."); + break; + } + case ERROR: + logger.log(Level.SEVERE, "Kill request error for VM ID " + request.getParameter("vm-id")); + break; + case PONG: // fall-through, also OK :) + case OK: + // TODO: Report this to user somehow (notification?) + logger.log(Level.INFO, "VM with id " + request.getParameter("vm-id") + " killed on host " + request.getTarget().toString()); + break; + default: + logger.log(Level.WARNING, "Unknown result from KILL VM command."); + break; + } + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/killvm/src/main/java/com/redhat/thermostat/client/killvm/locale/LocaleResources.java Thu Aug 30 17:37:39 2012 +0200 @@ -0,0 +1,53 @@ +/* + * Copyright 2012 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.client.killvm.locale; + +import com.redhat.thermostat.common.locale.Translate; + +public enum LocaleResources { + + ACTION_NAME, + ACTION_DESCRIPTION, + MISSING_INFO; + + public static final String RESOURCE_BUNDLE = + "com.redhat.thermostat.client.killvm.locale.strings"; + + public static Translate createLocalizer() { + return new Translate(RESOURCE_BUNDLE); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/killvm/src/main/resources/com/redhat/thermostat/client/killvm/locale/strings.properties Thu Aug 30 17:37:39 2012 +0200 @@ -0,0 +1,3 @@ +ACTION_NAME = Kill Application +ACTION_DESCRIPTION = Kill the selected VM Process +MISSING_INFO = Missing Information \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/killvm/src/test/java/com/redhat/thermostat/client/killvm/internal/ActivatorTest.java Thu Aug 30 17:37:39 2012 +0200 @@ -0,0 +1,69 @@ +/* + * Copyright 2012 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.client.killvm.internal; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.eq; +import static org.mockito.Matchers.isA; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.Dictionary; + +import org.junit.Test; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceRegistration; + +import com.redhat.thermostat.client.osgi.service.VMContextAction; + +public class ActivatorTest { + + @Test + public void startRegistersKillVMAction() throws Exception { + BundleContext ctx = mock(BundleContext.class); + ServiceRegistration serviceReg = mock(ServiceRegistration.class); + when(ctx.registerService(anyString(), any(), any(Dictionary.class))) + .thenReturn(serviceReg); + Activator activator = new Activator(); + activator.start(ctx); + verify(ctx).registerService(eq(VMContextAction.class.getName()), + isA(KillVMAction.class), any(Dictionary.class)); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/killvm/src/test/java/com/redhat/thermostat/client/killvm/internal/KillVMActionTest.java Thu Aug 30 17:37:39 2012 +0200 @@ -0,0 +1,143 @@ +/* + * Copyright 2012 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.client.killvm.internal; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.isA; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.net.InetSocketAddress; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import com.redhat.thermostat.client.command.RequestQueue; +import com.redhat.thermostat.client.osgi.service.VmFilter; +import com.redhat.thermostat.common.appctx.ApplicationContext; +import com.redhat.thermostat.common.appctx.ApplicationContextUtil; +import com.redhat.thermostat.common.command.Request; +import com.redhat.thermostat.common.dao.DAOFactory; +import com.redhat.thermostat.common.dao.HostRef; +import com.redhat.thermostat.common.dao.VmInfoDAO; +import com.redhat.thermostat.common.dao.VmRef; +import com.redhat.thermostat.common.model.VmInfo; +import com.redhat.thermostat.common.storage.Storage; +import com.redhat.thermostat.common.utils.OSGIUtils; + +@RunWith(PowerMockRunner.class) +@PrepareForTest(OSGIUtils.class) +public class KillVMActionTest { + + private KillVMAction action; + private DAOFactory factory; + + @Before + public void setUp() { + ApplicationContextUtil.resetApplicationContext(); + factory = mock(DAOFactory.class); + ApplicationContext.getInstance().setDAOFactory(factory); + action = new KillVMAction(); + } + + @After + public void teardown() { + factory = null; + action = null; + } + + @Test + public void killVMFilterOnlyMatchesLiveVMs() { + VmFilter filter = action.getFilter(); + VmRef matching = mock(VmRef.class); + VmInfoDAO vmInfoDao = mock(VmInfoDAO.class); + VmInfo vmInfo = mock(VmInfo.class); + when(factory.getVmInfoDAO()).thenReturn(vmInfoDao); + when(vmInfoDao.getVmInfo(matching)).thenReturn(vmInfo); + when(vmInfo.isAlive()).thenReturn(true); + assertTrue(filter.matches(matching)); + when(vmInfo.isAlive()).thenReturn(false); + assertFalse(filter.matches(matching)); + } + + @Test + public void canQueueKillRequest() { + Storage storage = mock(Storage.class); + when(factory.getStorage()).thenReturn(storage); + VmRef ref = mock(VmRef.class); + HostRef hostref = mock(HostRef.class); + when(ref.getAgent()).thenReturn(hostref); + String agentAddress = "127.0.0.1:8888"; + when(storage.getConfigListenAddress(hostref)).thenReturn(agentAddress); + final Request req = mock(Request.class); + KillVMAction action = new KillVMAction() { + @Override + Request getKillRequest(InetSocketAddress target) { + return req; + } + }; + OSGIUtils utils = mock(OSGIUtils.class); + PowerMockito.mockStatic(OSGIUtils.class); + when(OSGIUtils.getInstance()).thenReturn(utils); + RequestQueue queue = mock(RequestQueue.class); + when(utils.getService(RequestQueue.class)).thenReturn(queue); + action.execute(ref); + ArgumentCaptor<String> vmIdParamCaptor = ArgumentCaptor + .forClass(String.class); + verify(req).setParameter(vmIdParamCaptor.capture(), any(String.class)); + assertEquals("vm-id", vmIdParamCaptor.getValue()); + verify(req).addListener(isA(VMKilledListener.class)); + ArgumentCaptor<String> receiverCaptor = ArgumentCaptor + .forClass(String.class); + verify(req).setReceiver(receiverCaptor.capture()); + assertEquals( + "com.redhat.thermostat.agent.killvm.internal.KillVmReceiver", + receiverCaptor.getValue()); + verify(queue).putRequest(req); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/killvm/src/test/java/com/redhat/thermostat/client/killvm/locale/TranslateTest.java Thu Aug 30 17:37:39 2012 +0200 @@ -0,0 +1,90 @@ +/* + * Copyright 2012 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.client.killvm.locale; + +import java.io.IOException; +import java.util.Locale; +import java.util.Properties; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.redhat.thermostat.common.locale.Translate; + +public class TranslateTest { + + private Locale lang; + private Translate t; + + @Before + public void setUp() { + this.lang = Locale.getDefault(); + Locale.setDefault(Locale.US); + t = LocaleResources.createLocalizer(); + } + + @After + public void tearDown() { + Locale.setDefault(lang); + t = null; + } + + @Test + public void testLocalizeWithoutArguments() { + String testString = t.localize(LocaleResources.MISSING_INFO); + Assert.assertEquals("Missing Information", testString); + } + + @Test + public void testLocalizedStringsArePresent() throws IOException { + + String stringsResource = "/" + LocaleResources.RESOURCE_BUNDLE.replace(".", "/") + ".properties"; + + Properties props = new Properties(); + props.load(getClass().getResourceAsStream(stringsResource)); + + Assert.assertEquals(LocaleResources.values().length, props.values().size()); + for (LocaleResources resource : LocaleResources.values()) { + Assert.assertTrue("missing property from resource bound file: " + resource, + props.containsKey(resource.name())); + } + } + +}
--- a/distribution/config/bundles.properties Fri Aug 31 17:49:45 2012 +0200 +++ b/distribution/config/bundles.properties Thu Aug 30 17:37:39 2012 +0200 @@ -39,6 +39,7 @@ thermostat-common-command-@project.version@.jar, \ thermostat-agent-command-@project.version@.jar, \ thermostat-agent-heapdumper-@project.version@.jar, \ + thermostat-agent-killvm-@project.version@.jar, \ thermostat-thread-collector-@project.version@.jar, \ thermostat-thread-harvester-@project.version@.jar, \ thermostat-client-command-@project.version@.jar
--- a/distribution/pom.xml Fri Aug 31 17:49:45 2012 +0200 +++ b/distribution/pom.xml Thu Aug 30 17:37:39 2012 +0200 @@ -292,6 +292,11 @@ </dependency> <dependency> <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-agent-killvm</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> <artifactId>thermostat-common-core</artifactId> <version>${project.version}</version> </dependency>