Mercurial > hg > release > thermostat-1.4
changeset 1529:33ad3d556e28
Garbage Collection command addition.
Reviewed-by: jerboaa, neugens, omajid
Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2014-October/011328.html
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-gc/command/pom.xml Mon Oct 27 14:29:52 2014 -0400 @@ -0,0 +1,139 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + Copyright 2012-2014 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-vm-gc</artifactId> + <version>1.1.0-SNAPSHOT</version> + </parent> + + <artifactId>thermostat-vm-gc-command</artifactId> + <packaging>bundle</packaging> + + <name>Thermostat GC Plugin Command</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>com.redhat.thermostat</groupId> + <artifactId>thermostat-common-core</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.core</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.compendium</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-common-test</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-shared-config</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-client-cli</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-gc-remote-collector-client-common</artifactId> + <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-storage-core</artifactId> + <version>${project.version}</version> + </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-SymbolicName>com.redhat.thermostat.vm.gc.command</Bundle-SymbolicName> + <Bundle-Activator>com.redhat.thermostat.vm.gc.command.internal.Activator</Bundle-Activator> + <Export-Package> + com.redhat.thermostat.vm.gc.command + </Export-Package> + <Private-Package> + com.redhat.thermostat.vm.gc.command.internal, + com.redhat.thermostat.vm.gc.command.locale, + </Private-Package> + <!-- Do not autogenerate uses clauses in Manifests --> + <_nouses>true</_nouses> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + +</project> +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-gc/command/src/main/java/com/redhat/thermostat/vm/gc/command/internal/Activator.java Mon Oct 27 14:29:52 2014 -0400 @@ -0,0 +1,100 @@ +/* + * Copyright 2012-2014 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.vm.gc.command.internal; + +import java.util.Hashtable; +import java.util.Map; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceRegistration; + +import com.redhat.thermostat.client.command.RequestQueue; +import com.redhat.thermostat.common.MultipleServiceTracker; +import com.redhat.thermostat.common.cli.Command; +import com.redhat.thermostat.gc.remote.common.GCRequest; +import com.redhat.thermostat.storage.dao.AgentInfoDAO; +import com.redhat.thermostat.storage.dao.HostInfoDAO; +import com.redhat.thermostat.storage.dao.VmInfoDAO; + +public class Activator implements BundleActivator { + + private MultipleServiceTracker serviceTracker; + private ServiceRegistration registration; + + private final GCCommand command = new GCCommand(new GCCommandListener()); + + @Override + public void start(BundleContext context) throws Exception { + Class<?>[] serviceDeps = new Class<?>[] { + HostInfoDAO.class, + AgentInfoDAO.class, + VmInfoDAO.class, + GCRequest.class, + RequestQueue.class, + }; + + serviceTracker = new MultipleServiceTracker(context, serviceDeps, new MultipleServiceTracker.Action() { + @Override + public void dependenciesAvailable(Map<String, Object> services) { + HostInfoDAO hostDAO = (HostInfoDAO) services.get(HostInfoDAO.class.getName()); + AgentInfoDAO agentDao = (AgentInfoDAO) services.get(AgentInfoDAO.class.getName()); + VmInfoDAO vmInfoDAO = (VmInfoDAO) services.get(VmInfoDAO.class.getName()); + GCRequest request = (GCRequest) services.get(GCRequest.class.getName()); + + command.setServices(request, agentDao, hostDAO, vmInfoDAO); + } + + @Override + public void dependenciesUnavailable() { + command.setServices(null, null, null, null); + } + }); + + serviceTracker.open(); + + Hashtable<String,String> properties = new Hashtable<>(); + properties.put(Command.NAME, "gc"); + registration = context.registerService(Command.class.getName(), command, properties); + } + + @Override + public void stop(BundleContext context) throws Exception { + serviceTracker.close(); + registration.unregister(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-gc/command/src/main/java/com/redhat/thermostat/vm/gc/command/internal/GCCommand.java Mon Oct 27 14:29:52 2014 -0400 @@ -0,0 +1,143 @@ +/* + * Copyright 2012-2014 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.vm.gc.command.internal; + +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; + +import com.redhat.thermostat.client.cli.HostVMArguments; +import com.redhat.thermostat.common.cli.AbstractCommand; +import com.redhat.thermostat.common.cli.CommandContext; +import com.redhat.thermostat.common.cli.CommandException; +import com.redhat.thermostat.gc.remote.common.GCRequest; +import com.redhat.thermostat.shared.locale.Translate; +import com.redhat.thermostat.storage.core.HostRef; +import com.redhat.thermostat.storage.core.VmId; +import com.redhat.thermostat.storage.core.VmRef; +import com.redhat.thermostat.storage.dao.AgentInfoDAO; +import com.redhat.thermostat.storage.dao.HostInfoDAO; +import com.redhat.thermostat.storage.dao.VmInfoDAO; +import com.redhat.thermostat.storage.model.VmInfo; +import com.redhat.thermostat.vm.gc.command.locale.LocaleResources; + +public class GCCommand extends AbstractCommand { + + private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer(); + + private GCRequest request; + private AgentInfoDAO agentInfoDAO; + private VmInfoDAO vmInfoDAO; + private HostInfoDAO hostInfoDAO; + private final GCCommandListener listener; + private Semaphore servicesAvailable = new Semaphore(0); + + public GCCommand(GCCommandListener listener) { + this.listener = listener; + } + + @Override + public void run(CommandContext ctx) throws CommandException { + waitForServices(500l); + + requireNonNull(hostInfoDAO, translator.localize(LocaleResources.HOST_SERVICE_UNAVAILABLE)); + requireNonNull(vmInfoDAO, translator.localize(LocaleResources.VM_SERVICE_UNAVAILABLE)); + requireNonNull(agentInfoDAO, translator.localize(LocaleResources.AGENT_SERVICE_UNAVAILABLE)); + requireNonNull(request, translator.localize(LocaleResources.GCREQUEST_SERVICE_UNAVAILABLE)); + + listener.setOut(ctx.getConsole().getOutput()); + listener.setErr(ctx.getConsole().getError()); + + HostVMArguments args = new HostVMArguments(ctx.getArguments(), false, true); + + VmId vmId = new VmId(args.getVM().getVmId()); + attemptGC(vmId); + } + + private void waitForServices(long timeout) { + try { + servicesAvailable.tryAcquire(timeout, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + translator.localize(LocaleResources.COMMAND_INTERRUPTED); + } + } + + private void attemptGC(VmId vmId) throws CommandException { + VmInfo result = vmInfoDAO.getVmInfo(vmId); + + if (result == null) { + throw new CommandException(translator.localize(LocaleResources.VM_NOT_FOUND, vmId.get())); + } else { + HostRef dummyRef = new HostRef(result.getAgentId(), "dummy"); + sendGCRequest(new VmRef(dummyRef, result.getVmId(), result.getVmPid(), result.getVmName())); + } + } + + private void sendGCRequest(VmRef vmRef) throws CommandException { + request.sendGCRequestToAgent(vmRef, agentInfoDAO, listener); + + waitForListenerResponse(); + } + + private void waitForListenerResponse() { + try { + listener.await(1000l); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + public void setServices(GCRequest request, AgentInfoDAO agentInfoDAO, HostInfoDAO hostInfoDAO, VmInfoDAO vmInfoDAO) { + this.request = request; + this.agentInfoDAO = agentInfoDAO; + this.hostInfoDAO = hostInfoDAO; + this.vmInfoDAO = vmInfoDAO; + + if (request == null || agentInfoDAO == null || hostInfoDAO == null || vmInfoDAO == null) { + servicesUnavailable(); + } else { + servicesAvailable(); + } + } + + private void servicesAvailable() { + this.servicesAvailable.release(); + } + + private void servicesUnavailable() { + this.servicesAvailable.drainPermits(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-gc/command/src/main/java/com/redhat/thermostat/vm/gc/command/internal/GCCommandListener.java Mon Oct 27 14:29:52 2014 -0400 @@ -0,0 +1,106 @@ +/* + * Copyright 2012-2014 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.vm.gc.command.internal; + +import java.io.PrintStream; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +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; +import com.redhat.thermostat.common.utils.LoggingUtils; +import com.redhat.thermostat.shared.locale.Translate; +import com.redhat.thermostat.vm.gc.command.locale.LocaleResources; + +public class GCCommandListener implements RequestResponseListener { + private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer(); + private static final Logger logger = LoggingUtils + .getLogger(GCCommandListener.class); + + private final CountDownLatch latch = new CountDownLatch(1); + + private PrintStream out; + private PrintStream err; + + @Override + public void fireComplete(Request request, Response response) { + String message; + String pid; + + switch (response.getType()) { + case ERROR: + pid = request.getParameter("VM_PID"); + message = "GC Request error for VM PID " + pid; + logger.log(Level.SEVERE, message); + if (err != null) { + err.println(translator.localize(LocaleResources.GC_ERROR_RESULT, pid).getContents()); + } + break; + case OK: + pid = request.getParameter("VM_PID"); + message = "Garbage Collection performed on VM with PID " + pid; + logger.log(Level.INFO, message); + if (out != null) { + out.println(translator.localize(LocaleResources.GC_SUCCESS_RESULT, pid).getContents()); + } + break; + default: + message = "Unknown result from GC command"; + logger.log(Level.WARNING, message); + if (out != null) { + out.println(translator.localize(LocaleResources.GC_UNKNOWN_RESULT).getContents()); + } + break; + } + latch.countDown(); + } + + public synchronized void await(long timeout) throws InterruptedException { + this.latch.await(timeout, TimeUnit.MILLISECONDS); + } + + public void setOut(PrintStream out) { + this.out = out; + } + + public void setErr(PrintStream err) { + this.err = err; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-gc/command/src/main/java/com/redhat/thermostat/vm/gc/command/locale/LocaleResources.java Mon Oct 27 14:29:52 2014 -0400 @@ -0,0 +1,58 @@ +/* + * Copyright 2012-2014 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.vm.gc.command.locale; + +import com.redhat.thermostat.shared.locale.Translate; + +public enum LocaleResources { + + GCREQUEST_SERVICE_UNAVAILABLE, + GC_FAILED, + AGENT_SERVICE_UNAVAILABLE, + HOST_SERVICE_UNAVAILABLE, + VM_SERVICE_UNAVAILABLE, + LISTENER_UNAVAILABLE, + VM_NOT_FOUND, COMMAND_INTERRUPTED, GC_ERROR_RESULT, GC_SUCCESS_RESULT, GC_UNKNOWN_RESULT; + + static final String RESOURCE_BUNDLE = + "com.redhat.thermostat.gc.command.locale.strings"; + + public static Translate<LocaleResources> createLocalizer() { + return new Translate(RESOURCE_BUNDLE, LocaleResources.class); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-gc/command/src/main/resources/com/redhat/thermostat/gc/command/locale/strings.properties Mon Oct 27 14:29:52 2014 -0400 @@ -0,0 +1,11 @@ +GCREQUEST_SERVICE_UNAVAILABLE = Unable to get GCRequest service +GC_FAILED = Attempt to perform Garbage Collection failed +HOST_SERVICE_UNAVAILABLE = Unable to get host information (HostInfoDAO is unavailable) +VM_SERVICE_UNAVAILABLE = Unable to get vm information (VmInfoDAO is unavailable) +AGENT_SERVICE_UNAVAILABLE = Unable to get agent information (AgentInfoDAO is unavailable) +LISTENER_UNAVAILABLE = Unable to get listener +VM_NOT_FOUND = VM with ID: {0} not found +COMMAND_INTERRUPTED = Command interrupted while waiting for services. +GC_ERROR_RESULT = GC Request Error for VM with PID: {0} +GC_SUCCESS_RESULT = GC Successful for VM with PID: {0} +GC_UNKNOWN_RESULT = Unknown result for GC request \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-gc/command/src/test/java/com/redhat/thermostat/vm/gc/command/internal/ActivatorTest.java Mon Oct 27 14:29:52 2014 -0400 @@ -0,0 +1,60 @@ +/* + * Copyright 2012-2014 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.vm.gc.command.internal; + +import static com.redhat.thermostat.testutils.Asserts.assertCommandIsRegistered; +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.redhat.thermostat.testutils.StubBundleContext; + +public class ActivatorTest { + @Test + public void verifyCommandRegistered() throws Exception { + StubBundleContext context = new StubBundleContext(); + Activator activator = new Activator(); + + activator.start(context); + + assertCommandIsRegistered(context, "gc", GCCommand.class); + + activator.stop(context); + + assertEquals(0, context.getAllServices().size()); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-gc/command/src/test/java/com/redhat/thermostat/vm/gc/command/internal/GCCommandListenerTest.java Mon Oct 27 14:29:52 2014 -0400 @@ -0,0 +1,166 @@ +/* + * Copyright 2012-2014 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.vm.gc.command.internal; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.nio.charset.StandardCharsets; +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.LogRecord; +import java.util.logging.Logger; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + +import com.redhat.thermostat.common.command.Request; +import com.redhat.thermostat.common.command.Response; +import com.redhat.thermostat.common.utils.LoggingUtils; + +public class GCCommandListenerTest { + + private final GCCommandListener listener = new GCCommandListener(); + private static final Logger logger = LoggingUtils + .getLogger(GCCommandListener.class); + + private PrintStream ps; + private ByteArrayOutputStream baos; + + + @Before + public void setup() { + baos = new ByteArrayOutputStream(); + ps = new PrintStream(baos); + listener.setOut(ps); + listener.setErr(ps); + } + + @Test + public void testSuccessfulGCResponse() { + Request request = mock(Request.class); + + Response resp = new Response(Response.ResponseType.OK); + + Handler handler = mock(Handler.class); + logger.addHandler(handler); + + final boolean[] complete = {false}; + doAnswer(new Answer() { + @Override + public Object answer(InvocationOnMock invocation) throws Throwable { + LogRecord log = (LogRecord)invocation.getArguments()[0]; + if (log.getLevel().equals(Level.INFO)) { + complete[0] = true; + } + return null; + } + }).when(handler).publish(any(LogRecord.class)); + + listener.fireComplete(request, resp); + + assertTrue(complete[0]); + + String expected = "GC Successful for VM with PID: null\n"; + assertEquals(expected, new String(baos.toByteArray(), StandardCharsets.UTF_8)); + } + + @Test + public void testErrorResponse() { + Request request = mock(Request.class); + Response resp = new Response(Response.ResponseType.ERROR); + + Handler handler = mock(Handler.class); + logger.addHandler(handler); + + final boolean[] complete = {false}; + doAnswer(new Answer() { + @Override + public Object answer(InvocationOnMock invocation) throws Throwable { + LogRecord log = (LogRecord)invocation.getArguments()[0]; + if (log.getLevel().equals(Level.SEVERE)) { + complete[0] = true; + } + return null; + } + }).when(handler).publish(any(LogRecord.class)); + + listener.fireComplete(request, resp); + + assertTrue(complete[0]); + + String expected = "GC Request Error for VM with PID: null\n"; + assertEquals(expected, new String(baos.toByteArray(), StandardCharsets.UTF_8)); + } + + @Test + public void testDefaultResponse() { + Request request = mock(Request.class); + Response resp = new Response(Response.ResponseType.NOK); + + Handler handler = mock(Handler.class); + logger.addHandler(handler); + + final boolean[] complete = {false}; + doAnswer(new Answer() { + @Override + public Object answer(InvocationOnMock invocation) throws Throwable { + LogRecord log = (LogRecord)invocation.getArguments()[0]; + if (log.getLevel().equals(Level.WARNING)) { + complete[0] = true; + } + return null; + } + }).when(handler).publish(any(LogRecord.class)); + + listener.fireComplete(request, resp); + + assertTrue(complete[0]); + + assertTrue(baos.size() > 0); + + String expected = "Unknown result for GC request\n"; + assertEquals(expected, new String(baos.toByteArray(), StandardCharsets.UTF_8)); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-gc/command/src/test/java/com/redhat/thermostat/vm/gc/command/internal/GCCommandTest.java Mon Oct 27 14:29:52 2014 -0400 @@ -0,0 +1,149 @@ +/* + * Copyright 2012-2014 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.vm.gc.command.internal; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + +import com.redhat.thermostat.common.cli.CommandContext; +import com.redhat.thermostat.common.cli.CommandException; +import com.redhat.thermostat.common.cli.SimpleArguments; +import com.redhat.thermostat.gc.remote.common.GCRequest; +import com.redhat.thermostat.storage.core.HostRef; +import com.redhat.thermostat.storage.core.VmId; +import com.redhat.thermostat.storage.core.VmRef; +import com.redhat.thermostat.storage.dao.AgentInfoDAO; +import com.redhat.thermostat.storage.dao.HostInfoDAO; +import com.redhat.thermostat.storage.dao.VmInfoDAO; +import com.redhat.thermostat.storage.model.VmInfo; +import com.redhat.thermostat.test.TestCommandContextFactory; + +public class GCCommandTest { + + private GCCommand command; + private TestCommandContextFactory cmdCtxFactory; + + private HostInfoDAO hostInfoDAO; + private VmInfoDAO vmInfoDAO; + private AgentInfoDAO agentInfoDAO; + private GCRequest gcRequest; + private GCCommandListener listener; + + @Before + public void setup() { + cmdCtxFactory = new TestCommandContextFactory(); + + hostInfoDAO = mock(HostInfoDAO.class); + vmInfoDAO = mock(VmInfoDAO.class); + agentInfoDAO = mock(AgentInfoDAO.class); + gcRequest = mock(GCRequest.class); + + listener = mock(GCCommandListener.class); + + command = new GCCommand(listener); + } + + @Test + public void testPerformGC() throws Exception { + String vmId = "liveVM"; + + VmRef vmRef = new VmRef(new HostRef(null, "dummy"), "liveVM", -1, "dummy"); + + VmInfo vmInfo = mock(VmInfo.class); + when(vmInfo.getVmPid()).thenReturn(-1); + when(vmInfo.getVmId()).thenReturn("liveVM"); + when(vmInfo.getVmName()).thenReturn("dummy"); + + when(vmInfoDAO.getVmInfo(any(VmId.class))).thenReturn(vmInfo); + + final boolean[] complete = {false}; + doAnswer(new Answer() { + @Override + public Object answer(InvocationOnMock invocation) throws Throwable { + complete[0] = true; + return null; + } + }).when(gcRequest).sendGCRequestToAgent(vmRef, agentInfoDAO, listener); + + CommandContext context = createVmIdArgs(vmId); + + setServices(); + + command.run(context); + + assertTrue(complete[0]); + } + + @Test(expected = CommandException.class) + public void testPerformGCOnMissingVM() throws Exception { + String vmId = "nonexistentVM"; + + CommandContext context = createVmIdArgs(vmId); + + setServices(); + + command.run(context); + } + + @Test(expected = CommandException.class) + public void testGCWithoutServices() throws Exception { + String vmId = "liveVM"; + + CommandContext context = createVmIdArgs(vmId); + + command.run(context); + } + + private CommandContext createVmIdArgs(String vmId) { + SimpleArguments args = new SimpleArguments(); + args.addArgument("vmId", vmId); + return cmdCtxFactory.createContext(args); + } + + private void setServices() { + command.setServices(gcRequest, agentInfoDAO, hostInfoDAO, vmInfoDAO); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-gc/command/src/test/java/com/redhat/thermostat/vm/gc/command/locale/LocaleResourcesTest.java Mon Oct 27 14:29:52 2014 -0400 @@ -0,0 +1,51 @@ +/* + * Copyright 2012-2014 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.vm.gc.command.locale; + +import com.redhat.thermostat.testutils.AbstractLocaleResourcesTest; + +public class LocaleResourcesTest extends AbstractLocaleResourcesTest<LocaleResources> { + @Override + protected Class<LocaleResources> getEnumClass() { + return LocaleResources.class; + } + + @Override + protected String getResourceBundle() { + return LocaleResources.RESOURCE_BUNDLE; + } +}
--- a/vm-gc/distribution/pom.xml Mon Oct 27 12:48:15 2014 -0400 +++ b/vm-gc/distribution/pom.xml Mon Oct 27 14:29:52 2014 -0400 @@ -94,6 +94,11 @@ </dependency> <dependency> <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-vm-gc-command</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> <artifactId>thermostat-vm-gc-client-core</artifactId> <version>${project.version}</version> </dependency>
--- a/vm-gc/distribution/thermostat-plugin.xml Mon Oct 27 12:48:15 2014 -0400 +++ b/vm-gc/distribution/thermostat-plugin.xml Mon Oct 27 14:29:52 2014 -0400 @@ -39,6 +39,47 @@ <plugin xmlns="http://icedtea.classpath.org/thermostat/plugins/v1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://icedtea.classpath.org/thermostat/plugins/v1.0 thermostat-plugin.xsd"> + <commands> + <command> + <name>gc</name> + <description>Performs Garbage Collection on the given vm</description> + <options> + <option> + <long>vmId</long> + <short>v</short> + <argument>vm</argument> + <required>true</required> + <description>the ID of the VM</description> + </option> + </options> + <environments> + <environment>cli</environment> + <environment>shell</environment> + </environments> + <bundles> + <bundle><symbolic-name>com.redhat.thermostat.vm.gc.command</symbolic-name><version>${project.version}</version></bundle> + <bundle><symbolic-name>com.redhat.thermostat.gc.remote.client.common</symbolic-name><version>${project.version}</version></bundle> + <bundle><symbolic-name>com.redhat.thermostat.gc.remote.common.command</symbolic-name><version>${project.version}</version></bundle> + <bundle><symbolic-name>com.redhat.thermostat.common.command</symbolic-name><version>${project.version}</version></bundle> + <bundle><symbolic-name>com.redhat.thermostat.client.core</symbolic-name><version>${project.version}</version></bundle> + <bundle><symbolic-name>com.redhat.thermostat.client.command</symbolic-name><version>${project.version}</version></bundle> + <bundle><symbolic-name>com.redhat.thermostat.client.cli</symbolic-name><version>${project.version}</version></bundle> + <bundle><symbolic-name>com.redhat.thermostat.storage.mongodb</symbolic-name><version>${project.version}</version></bundle> + <bundle><symbolic-name>com.redhat.thermostat.web.common</symbolic-name><version>${project.version}</version></bundle> + <bundle><symbolic-name>com.redhat.thermostat.web.client</symbolic-name><version>${project.version}</version></bundle> + <bundle><symbolic-name>org.mongodb.mongo-java-driver</symbolic-name><version>${mongo-driver.osgi-version}</version></bundle> + <bundle><symbolic-name>org.apache.commons.beanutils</symbolic-name><version>${commons-beanutils.version}</version></bundle> + <bundle><symbolic-name>org.apache.commons.codec</symbolic-name><version>${commons-codec.osgi-version}</version></bundle> + <bundle><symbolic-name>org.apache.commons.collections</symbolic-name><version>${commons-collections.version}</version></bundle> + <bundle><symbolic-name>org.apache.commons.logging</symbolic-name><version>${commons-logging.version}</version></bundle> + <bundle><symbolic-name>org.apache.httpcomponents.httpcore</symbolic-name><version>${httpcomponents.core.version}</version></bundle> + <bundle><symbolic-name>org.apache.httpcomponents.httpclient</symbolic-name><version>${httpcomponents.client.version}</version></bundle> + <bundle><symbolic-name>${osgi.compendium.bundle.symbolic-name}</symbolic-name><version>${osgi.compendium.osgi-version}</version></bundle> + <bundle><symbolic-name>com.google.gson</symbolic-name><version>${gson.version}</version></bundle> + <bundle><symbolic-name>org.jboss.netty</symbolic-name><version>${netty.version}</version></bundle> + </bundles> + </command> + </commands> <extensions> <extension> <name>gui</name>
--- a/vm-gc/pom.xml Mon Oct 27 12:48:15 2014 -0400 +++ b/vm-gc/pom.xml Mon Oct 27 14:29:52 2014 -0400 @@ -54,6 +54,7 @@ <module>agent</module> <module>client-core</module> <module>client-swing</module> + <module>command</module> <module>common</module> <module>distribution</module> <module>remote-collector-command</module>
--- a/vm-gc/remote-collector-client-common/src/main/java/com/redhat/thermostat/gc/remote/client/common/RequestGCAction.java Mon Oct 27 12:48:15 2014 -0400 +++ b/vm-gc/remote-collector-client-common/src/main/java/com/redhat/thermostat/gc/remote/client/common/RequestGCAction.java Mon Oct 27 14:29:52 2014 -0400 @@ -38,26 +38,26 @@ import com.redhat.thermostat.common.ActionListener; import com.redhat.thermostat.common.ActionNotifier; -import com.redhat.thermostat.gc.remote.common.command.GCCommand; +import com.redhat.thermostat.gc.remote.common.command.GCAction; public class RequestGCAction { - private final ActionNotifier<GCCommand> notifier; + private final ActionNotifier<GCAction> notifier; public RequestGCAction() { notifier = new ActionNotifier<>(this); } - public void addActionListener(ActionListener<GCCommand> listener) { + public void addActionListener(ActionListener<GCAction> listener) { this.notifier.addActionListener(listener); } - public void removeActionListener(ActionListener<GCCommand> listener) { + public void removeActionListener(ActionListener<GCAction> listener) { this.notifier.removeActionListener(listener); } public void requestGC() { - notifier.fireAction(GCCommand.REQUEST_GC); + notifier.fireAction(GCAction.REQUEST_GC); } }
--- a/vm-gc/remote-collector-client-common/src/main/java/com/redhat/thermostat/gc/remote/common/GCRequest.java Mon Oct 27 12:48:15 2014 -0400 +++ b/vm-gc/remote-collector-client-common/src/main/java/com/redhat/thermostat/gc/remote/common/GCRequest.java Mon Oct 27 14:29:52 2014 -0400 @@ -42,7 +42,7 @@ import com.redhat.thermostat.common.command.Request; import com.redhat.thermostat.common.command.Request.RequestType; import com.redhat.thermostat.common.command.RequestResponseListener; -import com.redhat.thermostat.gc.remote.common.command.GCCommand; +import com.redhat.thermostat.gc.remote.common.command.GCAction; import com.redhat.thermostat.storage.core.HostRef; import com.redhat.thermostat.storage.core.VmRef; import com.redhat.thermostat.storage.dao.AgentInfoDAO; @@ -66,11 +66,11 @@ InetSocketAddress target = new InetSocketAddress(host[0], Integer.parseInt(host[1])); Request gcRequest = createRequest(target); - gcRequest.setReceiver(GCCommand.RECEIVER); + gcRequest.setReceiver(GCAction.RECEIVER); gcRequest.setParameter(Request.ACTION, CMD_CHANNEL_ACTION_NAME); - gcRequest.setParameter(GCCommand.class.getName(), GCCommand.REQUEST_GC.name()); - gcRequest.setParameter(GCCommand.VM_PID, String.valueOf(vm.getPid())); + gcRequest.setParameter(GCAction.class.getName(), GCAction.REQUEST_GC.name()); + gcRequest.setParameter(GCAction.VM_PID, String.valueOf(vm.getPid())); gcRequest.addListener(responseListener);
--- a/vm-gc/remote-collector-client-common/src/test/java/com/redhat/thermostat/gc/remote/common/GCRequestTest.java Mon Oct 27 12:48:15 2014 -0400 +++ b/vm-gc/remote-collector-client-common/src/test/java/com/redhat/thermostat/gc/remote/common/GCRequestTest.java Mon Oct 27 14:29:52 2014 -0400 @@ -49,7 +49,7 @@ import com.redhat.thermostat.client.command.RequestQueue; import com.redhat.thermostat.common.command.Request; import com.redhat.thermostat.common.command.RequestResponseListener; -import com.redhat.thermostat.gc.remote.common.command.GCCommand; +import com.redhat.thermostat.gc.remote.common.command.GCAction; import com.redhat.thermostat.storage.core.HostRef; import com.redhat.thermostat.storage.core.VmRef; import com.redhat.thermostat.storage.dao.AgentInfoDAO; @@ -113,9 +113,9 @@ assertTrue(results[1]); assertTrue(results[2]); - verify(request).setReceiver(GCCommand.RECEIVER); - verify(request).setParameter(GCCommand.class.getName(), GCCommand.REQUEST_GC.name()); - verify(request).setParameter(GCCommand.VM_PID, "123456"); + verify(request).setReceiver(GCAction.RECEIVER); + verify(request).setParameter(GCAction.class.getName(), GCAction.REQUEST_GC.name()); + verify(request).setParameter(GCAction.VM_PID, "123456"); verify(request).addListener(listener); verify(queue).putRequest(request);
--- a/vm-gc/remote-collector-command/pom.xml Mon Oct 27 12:48:15 2014 -0400 +++ b/vm-gc/remote-collector-command/pom.xml Mon Oct 27 14:29:52 2014 -0400 @@ -88,7 +88,12 @@ <artifactId>thermostat-agent-core</artifactId> <version>${project.version}</version> </dependency> - + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-common-test</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> </dependencies> <build> @@ -101,7 +106,7 @@ <instructions> <Bundle-Vendor>Red Hat, Inc.</Bundle-Vendor> <Bundle-SymbolicName>com.redhat.thermostat.gc.remote.command</Bundle-SymbolicName> - <Bundle-Activator>com.redhat.thermostat.gc.remote.command.osgi.GCCommandReceiverActivator</Bundle-Activator> + <Bundle-Activator>com.redhat.thermostat.gc.remote.command.osgi.Activator</Bundle-Activator> <Export-Package> com.redhat.thermostat.gc.remote.command, </Export-Package>
--- a/vm-gc/remote-collector-command/src/main/java/com/redhat/thermostat/gc/remote/command/GCCommandReceiver.java Mon Oct 27 12:48:15 2014 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,86 +0,0 @@ -/* - * Copyright 2012-2014 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.gc.remote.command; - -import java.util.logging.Level; -import java.util.logging.Logger; - -import com.redhat.thermostat.agent.command.RequestReceiver; -import com.redhat.thermostat.agent.utils.management.MXBeanConnectionPool; -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.common.utils.LoggingUtils; -import com.redhat.thermostat.gc.remote.command.internal.GC; -import com.redhat.thermostat.gc.remote.command.internal.GCException; -import com.redhat.thermostat.gc.remote.common.command.GCCommand; - -public class GCCommandReceiver implements RequestReceiver { - - private static final Logger logger = LoggingUtils.getLogger(GCCommandReceiver.class); - private MXBeanConnectionPool pool; - - public GCCommandReceiver(MXBeanConnectionPool pool) { - this.pool = pool; - } - - @Override - public Response receive(Request request) { - Response response = new Response(ResponseType.OK); - - String command = request.getParameter(GCCommand.class.getName()); - switch (GCCommand.valueOf(command)) { - case REQUEST_GC: - String strPid = request.getParameter(GCCommand.VM_PID); - try { - int vmId = Integer.parseInt(strPid); - new GC(pool, vmId).gc(); - } catch (GCException gce) { - response = new Response(ResponseType.ERROR); - logger.log(Level.WARNING, "GC request failed", gce); - } catch (NumberFormatException e) { - response = new Response(ResponseType.ERROR); - logger.log(Level.WARNING, "Invalid PID: " + strPid, e); - } - break; - default: - break; - } - return response; - } -} -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-gc/remote-collector-command/src/main/java/com/redhat/thermostat/gc/remote/command/GCRequestReceiver.java Mon Oct 27 14:29:52 2014 -0400 @@ -0,0 +1,86 @@ +/* + * Copyright 2012-2014 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.gc.remote.command; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.redhat.thermostat.agent.command.RequestReceiver; +import com.redhat.thermostat.agent.utils.management.MXBeanConnectionPool; +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.common.utils.LoggingUtils; +import com.redhat.thermostat.gc.remote.command.internal.GC; +import com.redhat.thermostat.gc.remote.command.internal.GCException; +import com.redhat.thermostat.gc.remote.common.command.GCAction; + +public class GCRequestReceiver implements RequestReceiver { + + private static final Logger logger = LoggingUtils.getLogger(GCRequestReceiver.class); + private MXBeanConnectionPool pool; + + public GCRequestReceiver(MXBeanConnectionPool pool) { + this.pool = pool; + } + + @Override + public Response receive(Request request) { + Response response = new Response(ResponseType.OK); + + String command = request.getParameter(GCAction.class.getName()); + switch (GCAction.valueOf(command)) { + case REQUEST_GC: + String strPid = request.getParameter(GCAction.VM_PID); + try { + int vmId = Integer.parseInt(strPid); + new GC(pool, vmId).gc(); + } catch (GCException gce) { + response = new Response(ResponseType.ERROR); + logger.log(Level.WARNING, "GC request failed", gce); + } catch (NumberFormatException e) { + response = new Response(ResponseType.ERROR); + logger.log(Level.WARNING, "Invalid PID: " + strPid, e); + } + break; + default: + break; + } + return response; + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-gc/remote-collector-command/src/main/java/com/redhat/thermostat/gc/remote/command/osgi/Activator.java Mon Oct 27 14:29:52 2014 -0400 @@ -0,0 +1,78 @@ +/* + * Copyright 2012-2014 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.gc.remote.command.osgi; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; +import org.osgi.util.tracker.ServiceTracker; + +import com.redhat.thermostat.agent.command.ReceiverRegistry; +import com.redhat.thermostat.agent.utils.management.MXBeanConnectionPool; +import com.redhat.thermostat.gc.remote.command.GCRequestReceiver; + +public class Activator implements BundleActivator { + + private ServiceTracker tracker; + + @Override + public void start(BundleContext context) throws Exception { + final ReceiverRegistry registry = new ReceiverRegistry(context); + + tracker = new ServiceTracker(context, MXBeanConnectionPool.class, null) { + @Override + public MXBeanConnectionPool addingService(ServiceReference reference) { + MXBeanConnectionPool pool = (MXBeanConnectionPool) super.addingService(reference); + registry.registerReceiver(new GCRequestReceiver(pool)); + return pool; + }; + + @Override + public void removedService(ServiceReference reference, Object service) { + registry.unregisterReceivers(); + super.removedService(reference, service); + }; + }; + tracker.open(); + } + + @Override + public void stop(BundleContext context) throws Exception { + tracker.close(); + } +} +
--- a/vm-gc/remote-collector-command/src/main/java/com/redhat/thermostat/gc/remote/command/osgi/GCCommandReceiverActivator.java Mon Oct 27 12:48:15 2014 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,76 +0,0 @@ -/* - * Copyright 2012-2014 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.gc.remote.command.osgi; - -import org.osgi.framework.BundleActivator; -import org.osgi.framework.BundleContext; -import org.osgi.framework.ServiceReference; -import org.osgi.util.tracker.ServiceTracker; - -import com.redhat.thermostat.agent.command.ReceiverRegistry; -import com.redhat.thermostat.agent.utils.management.MXBeanConnectionPool; -import com.redhat.thermostat.gc.remote.command.GCCommandReceiver; - -public class GCCommandReceiverActivator implements BundleActivator { - - ServiceTracker tracker; - - @Override - public void start(BundleContext context) throws Exception { - final ReceiverRegistry registry = new ReceiverRegistry(context); - - tracker = new ServiceTracker(context, MXBeanConnectionPool.class, null) { - public MXBeanConnectionPool addingService(ServiceReference reference) { - MXBeanConnectionPool pool = (MXBeanConnectionPool) super.addingService(reference); - registry.registerReceiver(new GCCommandReceiver(pool)); - return pool; - }; - - public void removedService(org.osgi.framework.ServiceReference reference, Object service) { - registry.unregisterReceivers(); - super.removedService(reference, service); - }; - }; - tracker.open(); - } - - @Override - public void stop(BundleContext context) throws Exception { - tracker.close(); - } -} -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-gc/remote-collector-command/src/test/java/com/redhat/thermostat/gc/remote/command/osgi/ActivatorTest.java Mon Oct 27 14:29:52 2014 -0400 @@ -0,0 +1,83 @@ +/* + * Copyright 2012-2014 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.gc.remote.command.osgi; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; + +import org.junit.Before; +import org.junit.Test; + +import com.redhat.thermostat.agent.command.RequestReceiver; +import com.redhat.thermostat.agent.utils.management.MXBeanConnectionPool; +import com.redhat.thermostat.gc.remote.command.GCRequestReceiver; +import com.redhat.thermostat.testutils.StubBundleContext; + +public class ActivatorTest { + + private StubBundleContext context; + private Activator activator; + + @Before + public void setup() { + context = new StubBundleContext(); + activator = new Activator(); + } + + @Test + public void verifyReceiverRegistered() throws Exception { + MXBeanConnectionPool mxBeanConnectionPool = mock(MXBeanConnectionPool.class); + context.registerService(MXBeanConnectionPool.class, mxBeanConnectionPool, null); + + activator.start(context); + + assertEquals(2, context.getAllServices().size()); + assertTrue(context.isServiceRegistered(RequestReceiver.class.getName(), GCRequestReceiver.class)); + + activator.stop(context); + } + + @Test + public void verifyActivatorDoesNotRegisterServiceOnMissingDeps() throws Exception { + activator.start(context); + + assertEquals(0, context.getAllServices().size()); + + activator.stop(context); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-gc/remote-collector-common/src/main/java/com/redhat/thermostat/gc/remote/common/command/GCAction.java Mon Oct 27 14:29:52 2014 -0400 @@ -0,0 +1,46 @@ +/* + * Copyright 2012-2014 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.gc.remote.common.command; + +public enum GCAction { + + REQUEST_GC; + + public static final String VM_PID = "VM_PID"; + public static final String RECEIVER = "com.redhat.thermostat.gc.remote.command.GCRequestReceiver"; +} +
--- a/vm-gc/remote-collector-common/src/main/java/com/redhat/thermostat/gc/remote/common/command/GCCommand.java Mon Oct 27 12:48:15 2014 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/* - * Copyright 2012-2014 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.gc.remote.common.command; - -public enum GCCommand { - - REQUEST_GC; - - public static final String VM_PID = "VM_PID"; - public static final String RECEIVER = "com.redhat.thermostat.gc.remote.command.GCCommandReceiver"; -} -
--- a/vm-memory/client-core/src/main/java/com/redhat/thermostat/vm/memory/client/core/MemoryStatsView.java Mon Oct 27 12:48:15 2014 -0400 +++ b/vm-memory/client-core/src/main/java/com/redhat/thermostat/vm/memory/client/core/MemoryStatsView.java Mon Oct 27 14:29:52 2014 -0400 @@ -39,7 +39,7 @@ import com.redhat.thermostat.client.core.views.BasicView; import com.redhat.thermostat.client.core.views.UIComponent; import com.redhat.thermostat.common.ActionListener; -import com.redhat.thermostat.gc.remote.common.command.GCCommand; +import com.redhat.thermostat.gc.remote.common.command.GCAction; import com.redhat.thermostat.shared.locale.LocalizedString; public abstract class MemoryStatsView extends BasicView implements UIComponent { @@ -48,7 +48,7 @@ public abstract void updateRegion(Payload region); public abstract void setEnableGCAction(boolean enable); - public abstract void addGCActionListener(ActionListener<GCCommand> listener); + public abstract void addGCActionListener(ActionListener<GCAction> listener); public abstract void requestRepaint();
--- a/vm-memory/client-core/src/main/java/com/redhat/thermostat/vm/memory/client/core/internal/MemoryStatsController.java Mon Oct 27 12:48:15 2014 -0400 +++ b/vm-memory/client-core/src/main/java/com/redhat/thermostat/vm/memory/client/core/internal/MemoryStatsController.java Mon Oct 27 14:29:52 2014 -0400 @@ -57,7 +57,7 @@ import com.redhat.thermostat.common.command.Response; import com.redhat.thermostat.common.command.Response.ResponseType; import com.redhat.thermostat.gc.remote.common.GCRequest; -import com.redhat.thermostat.gc.remote.common.command.GCCommand; +import com.redhat.thermostat.gc.remote.common.command.GCAction; import com.redhat.thermostat.shared.locale.LocalizedString; import com.redhat.thermostat.shared.locale.Translate; import com.redhat.thermostat.storage.core.VmRef; @@ -192,9 +192,9 @@ } }); - view.addGCActionListener(new ActionListener<GCCommand>() { + view.addGCActionListener(new ActionListener<GCAction>() { @Override - public void actionPerformed(ActionEvent<GCCommand> actionEvent) { + public void actionPerformed(ActionEvent<GCAction> actionEvent) { RequestResponseListener listener = new RequestResponseListener() { @Override public void fireComplete(Request request, Response response) {
--- a/vm-memory/client-core/src/test/java/com/redhat/thermostat/vm/memory/client/core/internal/MemoryStatsControllerTest.java Mon Oct 27 12:48:15 2014 -0400 +++ b/vm-memory/client-core/src/test/java/com/redhat/thermostat/vm/memory/client/core/internal/MemoryStatsControllerTest.java Mon Oct 27 14:29:52 2014 -0400 @@ -66,7 +66,7 @@ import com.redhat.thermostat.common.TimerFactory; import com.redhat.thermostat.common.command.RequestResponseListener; import com.redhat.thermostat.gc.remote.common.GCRequest; -import com.redhat.thermostat.gc.remote.common.command.GCCommand; +import com.redhat.thermostat.gc.remote.common.command.GCAction; import com.redhat.thermostat.storage.core.VmRef; import com.redhat.thermostat.storage.dao.AgentInfoDAO; import com.redhat.thermostat.storage.dao.VmInfoDAO; @@ -89,7 +89,7 @@ private Timer timer; private ActionListener<MemoryStatsView.Action> viewListener; - private ActionListener<GCCommand> gcActionListener; + private ActionListener<GCAction> gcActionListener; private MemoryStatsController controller; @@ -204,7 +204,7 @@ @Test public void testGCInvoked() { - gcActionListener.actionPerformed(new ActionEvent<>(view, GCCommand.REQUEST_GC)); + gcActionListener.actionPerformed(new ActionEvent<>(view, GCAction.REQUEST_GC)); verify(gcRequest).sendGCRequestToAgent(eq(ref), eq(agentDAO), isA(RequestResponseListener.class)); }
--- a/vm-memory/client-swing/src/main/java/com/redhat/thermostat/vm/memory/client/swing/internal/MemoryStatsViewImpl.java Mon Oct 27 12:48:15 2014 -0400 +++ b/vm-memory/client-swing/src/main/java/com/redhat/thermostat/vm/memory/client/swing/internal/MemoryStatsViewImpl.java Mon Oct 27 14:29:52 2014 -0400 @@ -55,7 +55,7 @@ import com.redhat.thermostat.common.ActionListener; import com.redhat.thermostat.gc.remote.client.common.RequestGCAction; import com.redhat.thermostat.gc.remote.client.swing.ToolbarGCButton; -import com.redhat.thermostat.gc.remote.common.command.GCCommand; +import com.redhat.thermostat.gc.remote.common.command.GCAction; import com.redhat.thermostat.shared.locale.LocalizedString; import com.redhat.thermostat.shared.locale.Translate; import com.redhat.thermostat.vm.memory.client.core.MemoryStatsView; @@ -138,7 +138,7 @@ } @Override - public void addGCActionListener(ActionListener<GCCommand> listener) { + public void addGCActionListener(ActionListener<GCAction> listener) { toolbarButtonAction.addActionListener(listener); }