changeset 752:6e37ef654022

Add remote GC request capabilities review-thread: http://icedtea.classpath.org/pipermail/thermostat/2012-October/003955.html reviewed-by: rkennke
author Mario Torre <neugens.limasoftware@gmail.com>
date Sat, 27 Oct 2012 11:28:19 +0200
parents 6c7b3cdb01c6
children 7182f8c2066f
files agent/core/pom.xml agent/core/src/main/java/com/redhat/thermostat/utils/management/MXBeanConnection.java agent/core/src/main/java/com/redhat/thermostat/utils/management/MXBeanConnector.java client/core/src/main/java/com/redhat/thermostat/client/ui/IconDescriptor.java client/memory-stats-panel/core/pom.xml client/memory-stats-panel/core/src/main/java/com/redhat/thermostat/client/stats/memory/core/MemoryStatsController.java client/memory-stats-panel/core/src/main/java/com/redhat/thermostat/client/stats/memory/core/MemoryStatsService.java client/memory-stats-panel/core/src/main/java/com/redhat/thermostat/client/stats/memory/core/MemoryStatsView.java client/memory-stats-panel/core/src/test/java/com/redhat/thermostat/client/stats/memory/core/MemoryStatsControllerTest.java client/memory-stats-panel/swing/pom.xml client/memory-stats-panel/swing/src/main/java/com/redhat/thermostat/client/stats/memory/swing/MemoryStatsPanelActivator.java client/memory-stats-panel/swing/src/main/java/com/redhat/thermostat/client/stats/memory/swing/MemoryStatsViewImpl.java distribution/config/commands/agent.properties distribution/config/commands/gui.properties distribution/pom.xml gc/pom.xml gc/remote-collector-client-common/pom.xml gc/remote-collector-client-common/src/main/java/com/redhat/thermostat/gc/remote/client/common/IconResources.java gc/remote-collector-client-common/src/main/java/com/redhat/thermostat/gc/remote/client/common/LocaleResources.java gc/remote-collector-client-common/src/main/java/com/redhat/thermostat/gc/remote/client/common/RequestGCAction.java gc/remote-collector-client-common/src/main/java/com/redhat/thermostat/gc/remote/client/common/osgi/GCCommandActivator.java gc/remote-collector-client-common/src/main/java/com/redhat/thermostat/gc/remote/common/GCRequest.java gc/remote-collector-client-common/src/main/resources/com/redhat/thermostat/gc/remote/client/common/strings.properties gc/remote-collector-client-common/src/test/java/com/redhat/thermostat/gc/remote/common/GCRequestTest.java gc/remote-collector-client-swing/pom.xml gc/remote-collector-client-swing/src/main/java/com/redhat/thermostat/gc/remote/client/swing/ToolbarGCButton.java gc/remote-collector-client-swing/src/test/java/com/redhat/thermostat/gc/remote/client/swing/ToolbarGCButtonTest.java gc/remote-collector-command/pom.xml gc/remote-collector-command/src/main/java/com/redhat/thermostat/gc/remote/command/GCCommandReceiver.java gc/remote-collector-command/src/main/java/com/redhat/thermostat/gc/remote/command/internal/GC.java gc/remote-collector-command/src/main/java/com/redhat/thermostat/gc/remote/command/osgi/GCCommandReceiverActivator.java gc/remote-collector-common/pom.xml gc/remote-collector-common/src/main/java/com/redhat/thermostat/gc/remote/common/command/GCCommand.java gc/remote-collector-common/src/main/resources/com/redhat/thermostat/gc/remote/client/common/gcSmall.png gc/remote-collector-common/src/main/resources/com/redhat/thermostat/gc/remote/client/common/strings.properties pom.xml thread/client-common/src/main/java/com/redhat/thermostat/thread/client/common/IconResources.java thread/collector/src/main/java/com/redhat/thermostat/thread/collector/HarvesterCommand.java thread/harvester/pom.xml thread/harvester/src/main/java/com/redhat/thermostat/thread/harvester/Harvester.java thread/harvester/src/main/java/com/redhat/thermostat/thread/harvester/management/MXBeanConnection.java thread/harvester/src/main/java/com/redhat/thermostat/thread/harvester/management/MXBeanConnector.java thread/harvester/src/test/java/com/redhat/thermostat/thread/harvester/HarvesterTest.java
diffstat 43 files changed, 1891 insertions(+), 220 deletions(-) [+]
line wrap: on
line diff
--- a/agent/core/pom.xml	Fri Oct 26 15:59:28 2012 +0200
+++ b/agent/core/pom.xml	Sat Oct 27 11:28:19 2012 +0200
@@ -104,6 +104,7 @@
               com.redhat.thermostat.backend,
               com.redhat.thermostat.utils.hostname,
               com.redhat.thermostat.utils,
+              com.redhat.thermostat.utils.management,
             </Export-Package>
             <Private-Package>
               com.redhat.thermostat.backend.sample,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/core/src/main/java/com/redhat/thermostat/utils/management/MXBeanConnection.java	Sat Oct 27 11:28:19 2012 +0200
@@ -0,0 +1,67 @@
+/*
+ * 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.utils.management;
+
+import java.io.Closeable;
+import java.io.IOException;
+
+import javax.management.JMX;
+import javax.management.MBeanServerConnection;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import javax.management.remote.JMXConnector;
+
+public class MXBeanConnection implements Closeable {
+
+    private JMXConnector connection;
+    private MBeanServerConnection mbsc;
+    
+    MXBeanConnection(JMXConnector connection, MBeanServerConnection mbsc) {
+        this.connection = connection;
+        this.mbsc = mbsc;
+    }
+    
+    public synchronized <E> E createProxy(String name, Class<? extends E> proxyClass) throws MalformedObjectNameException {
+        ObjectName objectName = new ObjectName(name);
+        return JMX.newMXBeanProxy(mbsc, objectName, proxyClass);
+    }
+    
+    @Override
+    public void close() throws IOException {
+        connection.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/core/src/main/java/com/redhat/thermostat/utils/management/MXBeanConnector.java	Sat Oct 27 11:28:19 2012 +0200
@@ -0,0 +1,121 @@
+/*
+ * 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.utils.management;
+
+import java.io.Closeable;
+import java.io.File;
+import java.io.IOException;
+import java.util.Properties;
+
+import javax.management.MBeanServerConnection;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXServiceURL;
+
+import com.redhat.thermostat.common.dao.VmRef;
+import com.sun.tools.attach.VirtualMachine;
+
+public class MXBeanConnector implements Closeable {
+
+    private static final String CONNECTOR_ADDRESS_PROPERTY = "com.sun.management.jmxremote.localConnectorAddress";
+    private String connectorAddress;
+    
+    private VirtualMachine vm;
+    
+    private boolean attached;
+    
+    private String reference;
+    
+    public MXBeanConnector(String reference) {
+        this.reference = reference;
+    }
+    
+    public MXBeanConnector(VmRef reference) {
+        this.reference = reference.getStringID();
+    }
+    
+    public synchronized void attach() throws Exception {
+        if (attached)
+            throw new IOException("Already attached");
+        
+        vm = VirtualMachine.attach(reference);
+        attached = true;
+        
+        Properties props = vm.getAgentProperties();
+        connectorAddress = props.getProperty(CONNECTOR_ADDRESS_PROPERTY);
+        if (connectorAddress == null) {
+           props = vm.getSystemProperties();
+           String home = props.getProperty("java.home");
+           String agent = home + File.separator + "lib" + File.separator + "management-agent.jar";
+           vm.loadAgent(agent);
+           
+           props = vm.getAgentProperties();
+           connectorAddress = props.getProperty(CONNECTOR_ADDRESS_PROPERTY);
+        }
+    }
+    
+    public synchronized MXBeanConnection connect() throws Exception {
+        
+        if (!attached)
+            throw new IOException("Agent not attached to target VM");
+        
+        JMXServiceURL url = new JMXServiceURL(connectorAddress);
+        JMXConnector connection = JMXConnectorFactory.connect(url);
+        MBeanServerConnection mbsc = null;
+        try {
+            mbsc = connection.getMBeanServerConnection();
+            
+        } catch (IOException e) {
+            connection.close();
+            throw e;
+        }
+        
+        return new MXBeanConnection(connection, mbsc);
+    }
+    
+    public boolean isAttached() {
+        return attached;
+    }
+    
+    @Override
+    public synchronized void close() throws IOException {
+        if (attached) {
+            vm.detach();
+            attached = false;
+        }
+    }
+}
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/IconDescriptor.java	Fri Oct 26 15:59:28 2012 +0200
+++ b/client/core/src/main/java/com/redhat/thermostat/client/ui/IconDescriptor.java	Sat Oct 27 11:28:19 2012 +0200
@@ -40,6 +40,8 @@
 import java.io.InputStream;
 
 import java.nio.ByteBuffer;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 /**
  * Class that encapsulates an images raw data.
@@ -56,6 +58,8 @@
  */
 public class IconDescriptor {
 
+    private static final Logger logger = Logger.getLogger(IconDescriptor.class.getSimpleName());
+
     private ByteBuffer data;
     private int hash;
     
@@ -90,6 +94,25 @@
         return true;
     }
 
+    /**
+     * Loads an icon by calling
+     * {@link #createFromClassloader(ClassLoader, String)} with the system
+     * {@link ClassLoader}.
+     * 
+     * <br /><br />
+     * 
+     * This method doesn't throw {@link IOException}, it returns {@code null}
+     * on failure and logs the error.
+     */
+    public static IconDescriptor loadIcon(String name) {
+        try {
+            return IconDescriptor.createFromClassloader(ClassLoader.getSystemClassLoader(), name);
+        } catch (IOException e) {
+            logger.log(Level.WARNING, "Can't load " + name, e);
+        }
+        return null;
+    }
+    
     public static IconDescriptor createFromClassloader(ClassLoader classloader,
                                                        String resource) throws IOException
     {
--- a/client/memory-stats-panel/core/pom.xml	Fri Oct 26 15:59:28 2012 +0200
+++ b/client/memory-stats-panel/core/pom.xml	Sat Oct 27 11:28:19 2012 +0200
@@ -66,5 +66,15 @@
       <artifactId>thermostat-client-core</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-gc-remote-collector-client-common</artifactId>
+      <version>${project.version}</version>
+    </dependency>    
   </dependencies>
 </project>
--- a/client/memory-stats-panel/core/src/main/java/com/redhat/thermostat/client/stats/memory/core/MemoryStatsController.java	Fri Oct 26 15:59:28 2012 +0200
+++ b/client/memory-stats-panel/core/src/main/java/com/redhat/thermostat/client/stats/memory/core/MemoryStatsController.java	Sat Oct 27 11:28:19 2012 +0200
@@ -51,6 +51,7 @@
 import com.redhat.thermostat.common.Timer;
 import com.redhat.thermostat.common.Timer.SchedulingType;
 import com.redhat.thermostat.common.appctx.ApplicationContext;
+import com.redhat.thermostat.common.dao.AgentInfoDAO;
 import com.redhat.thermostat.common.dao.VmMemoryStatDAO;
 import com.redhat.thermostat.common.dao.VmRef;
 import com.redhat.thermostat.common.locale.Translate;
@@ -58,6 +59,8 @@
 import com.redhat.thermostat.common.model.VmMemoryStat.Generation;
 import com.redhat.thermostat.common.model.VmMemoryStat.Space;
 import com.redhat.thermostat.common.utils.DisplayableValues.Scale;
+import com.redhat.thermostat.gc.remote.common.GCRequest;
+import com.redhat.thermostat.gc.remote.common.command.GCCommand;
 
 class MemoryStatsController implements VmInformationServiceController {
 
@@ -139,7 +142,9 @@
         }
     }
     
-    public MemoryStatsController(final VmMemoryStatDAO vmMemoryStatDao, final VmRef ref, MemoryStatsViewProvider viewProvider) {
+    public MemoryStatsController(final VmMemoryStatDAO vmMemoryStatDao, final VmRef ref,
+                                 MemoryStatsViewProvider viewProvider,
+                                 final AgentInfoDAO agentDAO, final GCRequest gcRequest) {
         
         regions = new HashMap<>();
         this.ref = ref;
@@ -173,6 +178,13 @@
                 }
             }
         });
+        
+        view.addGCActionListener(new ActionListener<GCCommand>() {
+            @Override
+            public void actionPerformed(ActionEvent<GCCommand> actionEvent) {
+                gcRequest.sendGCRequestToAgent(ref, agentDAO);
+            }
+        });
     }
     
     // for testing
--- a/client/memory-stats-panel/core/src/main/java/com/redhat/thermostat/client/stats/memory/core/MemoryStatsService.java	Fri Oct 26 15:59:28 2012 +0200
+++ b/client/memory-stats-panel/core/src/main/java/com/redhat/thermostat/client/stats/memory/core/MemoryStatsService.java	Sat Oct 27 11:28:19 2012 +0200
@@ -40,24 +40,30 @@
 import com.redhat.thermostat.client.core.VmInformationService;
 import com.redhat.thermostat.client.core.controllers.VmInformationServiceController;
 import com.redhat.thermostat.client.osgi.service.AlwaysMatchFilter;
+import com.redhat.thermostat.common.dao.AgentInfoDAO;
 import com.redhat.thermostat.common.dao.VmMemoryStatDAO;
 import com.redhat.thermostat.common.dao.VmRef;
 import com.redhat.thermostat.common.utils.OSGIUtils;
+import com.redhat.thermostat.gc.remote.common.GCRequest;
 
 public class MemoryStatsService implements VmInformationService {
     
     private VmFilter filter = new AlwaysMatchFilter();
 
     private VmMemoryStatDAO vmMemoryStatDao;
-
-    public MemoryStatsService(VmMemoryStatDAO vmMemoryStatDao) {
+    private AgentInfoDAO agentDAO;
+    private GCRequest gcRequest;
+    
+    public MemoryStatsService(VmMemoryStatDAO vmMemoryStatDao, AgentInfoDAO agentDAO, GCRequest gcRequest) {
         this.vmMemoryStatDao = vmMemoryStatDao;
+        this.gcRequest = gcRequest;
+        this.agentDAO = agentDAO;
     }
     
     @Override
     public VmInformationServiceController getInformationServiceController(VmRef ref) {
         MemoryStatsViewProvider viewProvider = OSGIUtils.getInstance().getService(MemoryStatsViewProvider.class);
-        return new MemoryStatsController(vmMemoryStatDao, ref, viewProvider);
+        return new MemoryStatsController(vmMemoryStatDao, ref, viewProvider, agentDAO, gcRequest);
     }
 
     @Override
--- a/client/memory-stats-panel/core/src/main/java/com/redhat/thermostat/client/stats/memory/core/MemoryStatsView.java	Fri Oct 26 15:59:28 2012 +0200
+++ b/client/memory-stats-panel/core/src/main/java/com/redhat/thermostat/client/stats/memory/core/MemoryStatsView.java	Sat Oct 27 11:28:19 2012 +0200
@@ -38,11 +38,15 @@
 
 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;
 
 public abstract class MemoryStatsView extends BasicView implements UIComponent {
     
     public abstract void addRegion(Payload region);
     public abstract void updateRegion(Payload region);
     
-    public abstract void requestRepaint();
+    public abstract void addGCActionListener(ActionListener<GCCommand> listener);
+    
+    public abstract void requestRepaint();    
 }
--- a/client/memory-stats-panel/core/src/test/java/com/redhat/thermostat/client/stats/memory/core/MemoryStatsControllerTest.java	Fri Oct 26 15:59:28 2012 +0200
+++ b/client/memory-stats-panel/core/src/test/java/com/redhat/thermostat/client/stats/memory/core/MemoryStatsControllerTest.java	Sat Oct 27 11:28:19 2012 +0200
@@ -65,11 +65,14 @@
 import com.redhat.thermostat.common.TimerFactory;
 import com.redhat.thermostat.common.appctx.ApplicationContext;
 import com.redhat.thermostat.common.appctx.ApplicationContextUtil;
+import com.redhat.thermostat.common.dao.AgentInfoDAO;
 import com.redhat.thermostat.common.dao.VmMemoryStatDAO;
 import com.redhat.thermostat.common.dao.VmRef;
 import com.redhat.thermostat.common.model.VmMemoryStat;
 import com.redhat.thermostat.common.model.VmMemoryStat.Generation;
 import com.redhat.thermostat.common.model.VmMemoryStat.Space;
+import com.redhat.thermostat.gc.remote.common.GCRequest;
+import com.redhat.thermostat.gc.remote.common.command.GCCommand;
 
 public class MemoryStatsControllerTest {
 
@@ -80,11 +83,16 @@
     private Timer timer;
     
     private ActionListener<MemoryStatsView.Action> viewListener;
-    
+    private ActionListener<GCCommand> gcActionListener;
+
     private MemoryStatsController controller;
     
     private Space canary;
 
+    private AgentInfoDAO agentDAO;
+    private GCRequest gcRequest;
+    
+    private VmRef ref;
     
     @SuppressWarnings({ "unchecked", "rawtypes" })
     @Before
@@ -142,11 +150,19 @@
                 ArgumentCaptor.forClass(ActionListener.class);
         doNothing().when(view).addActionListener(viewArgumentCaptor.capture());
 
-        VmRef ref = mock(VmRef.class);
+        ArgumentCaptor<ActionListener> gcArgumentCaptor =
+                ArgumentCaptor.forClass(ActionListener.class);
+        doNothing().when(view).addGCActionListener(gcArgumentCaptor.capture());
         
-        controller = new MemoryStatsController(memoryStatDao, ref, viewProvider);
+        ref = mock(VmRef.class);
+        
+        agentDAO = mock(AgentInfoDAO.class);
+        gcRequest = mock(GCRequest.class);
+        
+        controller = new MemoryStatsController(memoryStatDao, ref, viewProvider, agentDAO, gcRequest);
         
         viewListener = viewArgumentCaptor.getValue();
+        gcActionListener = gcArgumentCaptor.getValue();
     }
     
     @Test
@@ -162,6 +178,12 @@
     }
 
     @Test
+    public void testGCInvoked() {
+        gcActionListener.actionPerformed(new ActionEvent<>(view, GCCommand.REQUEST_GC));
+        verify(gcRequest).sendGCRequestToAgent(ref, agentDAO);
+    }
+    
+    @Test
     public void testPayloadContainSpaces() {
         MemoryStatsController.VMCollector collettor = controller.getCollector();
         collettor.run();
--- a/client/memory-stats-panel/swing/pom.xml	Fri Oct 26 15:59:28 2012 +0200
+++ b/client/memory-stats-panel/swing/pom.xml	Sat Oct 27 11:28:19 2012 +0200
@@ -81,5 +81,17 @@
       <artifactId>thermostat-client-swing</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-gc-remote-collector-client-swing</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+        
   </dependencies>
 </project>
--- a/client/memory-stats-panel/swing/src/main/java/com/redhat/thermostat/client/stats/memory/swing/MemoryStatsPanelActivator.java	Fri Oct 26 15:59:28 2012 +0200
+++ b/client/memory-stats-panel/swing/src/main/java/com/redhat/thermostat/client/stats/memory/swing/MemoryStatsPanelActivator.java	Sat Oct 27 11:28:19 2012 +0200
@@ -48,7 +48,9 @@
 import com.redhat.thermostat.client.stats.memory.core.MemoryStatsViewProvider;
 import com.redhat.thermostat.common.MultipleServiceTracker;
 import com.redhat.thermostat.common.MultipleServiceTracker.Action;
+import com.redhat.thermostat.common.dao.AgentInfoDAO;
 import com.redhat.thermostat.common.dao.VmMemoryStatDAO;
+import com.redhat.thermostat.gc.remote.common.GCRequest;
 
 public class MemoryStatsPanelActivator implements BundleActivator {
 
@@ -63,6 +65,8 @@
         Class<?>[] deps = new Class<?>[] {
             ApplicationService.class,
             VmMemoryStatDAO.class,
+            GCRequest.class,
+            AgentInfoDAO.class,
         };
 
         tracker = new MultipleServiceTracker(context, deps, new Action() {
@@ -76,7 +80,10 @@
             @Override
             public void dependenciesAvailable(Map<String, Object> services) {
                 VmMemoryStatDAO memoryStatDao = (VmMemoryStatDAO) services.get(VmMemoryStatDAO.class.getName());
-                MemoryStatsService impl = new MemoryStatsService(memoryStatDao);
+                AgentInfoDAO agentDAO = (AgentInfoDAO) services.get(AgentInfoDAO.class.getName());
+                GCRequest gcRequest = (GCRequest) services.get(GCRequest.class.getName());
+
+                MemoryStatsService impl = new MemoryStatsService(memoryStatDao, agentDAO, gcRequest);
                 memoryStatRegistration = context.registerService(VmInformationService.class.getName(), impl , null);
             }
         });
--- a/client/memory-stats-panel/swing/src/main/java/com/redhat/thermostat/client/stats/memory/swing/MemoryStatsViewImpl.java	Fri Oct 26 15:59:28 2012 +0200
+++ b/client/memory-stats-panel/swing/src/main/java/com/redhat/thermostat/client/stats/memory/swing/MemoryStatsViewImpl.java	Sat Oct 27 11:28:19 2012 +0200
@@ -53,6 +53,10 @@
 import com.redhat.thermostat.client.swing.SwingComponent;
 import com.redhat.thermostat.client.swing.components.HeaderPanel;
 import com.redhat.thermostat.client.ui.ComponentVisibleListener;
+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;
 
 public class MemoryStatsViewImpl extends MemoryStatsView implements SwingComponent {
 
@@ -64,6 +68,8 @@
     
     private final Map<String, MemoryGraphPanel> regions;
     
+    private RequestGCAction toobarButtonAction;
+    
     private Dimension preferredSize;
     
     public MemoryStatsViewImpl() {
@@ -90,6 +96,9 @@
         realPanel = new JPanel();
         realPanel.setLayout(new BoxLayout(realPanel, BoxLayout.Y_AXIS));
         visiblePanel.setContent(realPanel);
+        
+        toobarButtonAction = new RequestGCAction();
+        visiblePanel.addToolBarButton(new ToolbarGCButton(toobarButtonAction));
     }
     
     @Transient
@@ -109,6 +118,11 @@
     }
     
     @Override
+    public void addGCActionListener(ActionListener<GCCommand> listener) {
+        toobarButtonAction.addActionListener(listener);
+    }
+    
+    @Override
     public void addRegion(final Payload region) {
 
         SwingUtilities.invokeLater(new Runnable() {
--- a/distribution/config/commands/agent.properties	Fri Oct 26 15:59:28 2012 +0200
+++ b/distribution/config/commands/agent.properties	Sat Oct 27 11:28:19 2012 +0200
@@ -9,6 +9,8 @@
           thermostat-thread-collector-@project.version@.jar, \
           thermostat-thread-harvester-@project.version@.jar, \
           thermostat-system-backend-@project.version@.jar, \
+          thermostat-gc-remote-collector-common-@project.version@.jar, \
+          thermostat-gc-remote-collector-command-@project.version@.jar, \
           netty.jar
 
 description = starts and stops the thermostat agent
--- a/distribution/config/commands/gui.properties	Fri Oct 26 15:59:28 2012 +0200
+++ b/distribution/config/commands/gui.properties	Sat Oct 27 11:28:19 2012 +0200
@@ -20,6 +20,9 @@
           thermostat-thread-client-swing-@project.version@.jar, \
           thermostat-thread-client-controllers-@project.version@.jar, \
           thermostat-thread-client-common-@project.version@.jar, \
+          thermostat-gc-remote-collector-common-@project.version@.jar, \
+          thermostat-gc-remote-collector-client-common-@project.version@.jar, \
+          thermostat-gc-remote-collector-client-swing-@project.version@.jar, \
           thermostat-osgi-process-handler-@project.version@.jar, \
           httpcore-osgi-@httpcomponents.version@.jar, \
           httpclient-osgi-@httpcomponents.version@.jar, \
--- a/distribution/pom.xml	Fri Oct 26 15:59:28 2012 +0200
+++ b/distribution/pom.xml	Sat Oct 27 11:28:19 2012 +0200
@@ -434,6 +434,28 @@
         <artifactId>thermostat-system-backend</artifactId>
         <version>${project.version}</version>
     </dependency>
-     
+    
+    <!-- new GC plugin -->
+    <dependency>
+        <groupId>com.redhat.thermostat</groupId>
+        <artifactId>thermostat-gc-remote-collector-common</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-gc-remote-collector-client-swing</artifactId>
+        <version>${project.version}</version>
+    </dependency>
+    <dependency>
+        <groupId>com.redhat.thermostat</groupId>
+        <artifactId>thermostat-gc-remote-collector-command</artifactId>
+        <version>${project.version}</version>
+    </dependency>
+         
   </dependencies>
 </project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gc/pom.xml	Sat Oct 27 11:28:19 2012 +0200
@@ -0,0 +1,68 @@
+<?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</artifactId>
+    <version>0.5.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>thermostat-gc</artifactId>
+  <packaging>pom</packaging>
+
+  <name>Thermostat GC Analysis And Remote GC Plugin</name>
+
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <modules>
+    <module>remote-collector-command</module>
+    <module>remote-collector-client-common</module>
+    <module>remote-collector-client-swing</module>
+    <module>remote-collector-common</module>
+  </modules>
+</project>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gc/remote-collector-client-common/pom.xml	Sat Oct 27 11:28:19 2012 +0200
@@ -0,0 +1,133 @@
+<?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-gc</artifactId>
+    <version>0.5.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>thermostat-gc-remote-collector-client-common</artifactId>
+  <packaging>bundle</packaging>
+
+  <name>Thermostat GC Plugin Common Client API</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-client-command</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-client-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-gc-remote-collector-common</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.gc.remote.client.common</Bundle-SymbolicName>
+            <Bundle-Activator>com.redhat.thermostat.gc.remote.client.common.osgi.GCCommandActivator</Bundle-Activator>
+            <Export-Package>
+                com.redhat.thermostat.gc.remote.client.common,
+                com.redhat.thermostat.gc.remote.common,
+            </Export-Package>
+            <Private-Package>
+                com.redhat.thermostat.gc.remote.client.common.osgi,
+            </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/gc/remote-collector-client-common/src/main/java/com/redhat/thermostat/gc/remote/client/common/IconResources.java	Sat Oct 27 11:28:19 2012 +0200
@@ -0,0 +1,51 @@
+/*
+ * 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.gc.remote.client.common;
+
+import com.redhat.thermostat.client.ui.IconDescriptor;
+
+public class IconResources {
+
+    private static IconDescriptor gcIconSmall;
+    
+    public synchronized static IconDescriptor getGCIconSmall() {
+        if (gcIconSmall == null) {
+            gcIconSmall = IconDescriptor.loadIcon("com/redhat/thermostat/gc/remote/client/common/gcSmall.png");
+        }
+        return gcIconSmall;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gc/remote-collector-client-common/src/main/java/com/redhat/thermostat/gc/remote/client/common/LocaleResources.java	Sat Oct 27 11:28:19 2012 +0200
@@ -0,0 +1,50 @@
+/*
+ * 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.gc.remote.client.common;
+
+import com.redhat.thermostat.common.locale.Translate;
+
+public enum LocaleResources {
+
+    PERFORM_GC;
+    
+    static final String RESOURCE_BUNDLE = "com.redhat.thermostat.gc.remote.client.common.strings";
+
+    public static Translate<LocaleResources> createLocalizer() {
+        return new Translate<>(RESOURCE_BUNDLE, LocaleResources.class);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gc/remote-collector-client-common/src/main/java/com/redhat/thermostat/gc/remote/client/common/RequestGCAction.java	Sat Oct 27 11:28:19 2012 +0200
@@ -0,0 +1,62 @@
+/*
+ * 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.gc.remote.client.common;
+
+import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.ActionNotifier;
+import com.redhat.thermostat.gc.remote.common.command.GCCommand;
+
+public class RequestGCAction {
+    
+    private final ActionNotifier<GCCommand> notifier;
+    
+    public RequestGCAction() {
+        notifier = new ActionNotifier<>(this);
+    }
+    
+    public void addActionListener(ActionListener<GCCommand> listener) {
+        this.notifier.addActionListener(listener);
+    }
+    
+    public void removeActionListener(ActionListener<GCCommand> listener) {
+        this.notifier.removeActionListener(listener);
+    }
+    
+    public void requestGC() {
+        notifier.fireAction(GCCommand.REQUEST_GC);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gc/remote-collector-client-common/src/main/java/com/redhat/thermostat/gc/remote/client/common/osgi/GCCommandActivator.java	Sat Oct 27 11:28:19 2012 +0200
@@ -0,0 +1,81 @@
+/*
+ * 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.gc.remote.client.common.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.client.command.RequestQueue;
+import com.redhat.thermostat.gc.remote.common.GCRequest;
+
+@SuppressWarnings({ "rawtypes", "unchecked" })
+public class GCCommandActivator implements BundleActivator {
+
+    private ServiceTracker tracker;
+
+    @Override
+    public void start(final BundleContext context) throws Exception {
+        tracker = new ServiceTracker(context, RequestQueue.class, null) {
+            @Override
+            public Object addingService(ServiceReference reference) {
+                System.err.println("starting GCCommandActivator");
+                
+                RequestQueue requestqueue = (RequestQueue) context.getService(reference);
+                
+                GCRequest gcRequest = new GCRequest(requestqueue); 
+                context.registerService(GCRequest.class, gcRequest, null);
+                return super.addingService(reference);
+            }
+            
+            @Override
+            public void removedService(ServiceReference reference, Object service) {
+                
+                context.ungetService(reference);
+                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/gc/remote-collector-client-common/src/main/java/com/redhat/thermostat/gc/remote/common/GCRequest.java	Sat Oct 27 11:28:19 2012 +0200
@@ -0,0 +1,78 @@
+/*
+ * 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.gc.remote.common;
+
+import java.net.InetSocketAddress;
+
+import com.redhat.thermostat.client.command.RequestQueue;
+import com.redhat.thermostat.common.command.Request;
+import com.redhat.thermostat.common.command.Request.RequestType;
+import com.redhat.thermostat.common.dao.AgentInfoDAO;
+import com.redhat.thermostat.common.dao.HostRef;
+import com.redhat.thermostat.common.dao.VmRef;
+import com.redhat.thermostat.gc.remote.common.command.GCCommand;
+
+public class GCRequest {
+    
+    private RequestQueue queue;
+    public GCRequest(RequestQueue queue) {
+        this.queue = queue;
+    }
+        
+    public void sendGCRequestToAgent(VmRef vm, AgentInfoDAO agentDAO) {
+                
+        HostRef targetHostRef = vm.getAgent();
+
+        String address = agentDAO.getAgentInformation(targetHostRef).getConfigListenAddress();
+        String [] host = address.split(":");
+        
+        InetSocketAddress target = new InetSocketAddress(host[0], Integer.parseInt(host[1]));
+        Request gcRequest = createRequest(target);
+
+        gcRequest.setReceiver(GCCommand.RECEIVER);
+
+        gcRequest.setParameter(GCCommand.class.getName(), GCCommand.REQUEST_GC.name());
+        gcRequest.setParameter(GCCommand.VM_ID, vm.getIdString());
+        
+        queue.putRequest(gcRequest);
+    }
+    
+    // for testing
+    Request createRequest(InetSocketAddress target) {
+        return new Request(RequestType.NO_RESPONSE_EXPECTED, target);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gc/remote-collector-client-common/src/main/resources/com/redhat/thermostat/gc/remote/client/common/strings.properties	Sat Oct 27 11:28:19 2012 +0200
@@ -0,0 +1,1 @@
+PERFORM_GC = Perform GC
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gc/remote-collector-client-common/src/test/java/com/redhat/thermostat/gc/remote/common/GCRequestTest.java	Sat Oct 27 11:28:19 2012 +0200
@@ -0,0 +1,118 @@
+/*
+ * 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.gc.remote.common;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.verify;
+
+import java.net.InetSocketAddress;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.redhat.thermostat.client.command.RequestQueue;
+import com.redhat.thermostat.common.command.Request;
+import com.redhat.thermostat.common.dao.AgentInfoDAO;
+import com.redhat.thermostat.common.dao.HostRef;
+import com.redhat.thermostat.common.dao.VmRef;
+import com.redhat.thermostat.common.model.AgentInformation;
+import com.redhat.thermostat.gc.remote.common.command.GCCommand;
+
+public class GCRequestTest {
+
+    private AgentInfoDAO agentDAO;
+    private RequestQueue queue;
+    private VmRef vm;
+
+    private GCRequest gcRequest;
+    private Request request;
+    
+    @Before
+    public void setUp() {
+        agentDAO = mock(AgentInfoDAO.class);
+        vm = mock(VmRef.class);
+
+        request = mock(Request.class);
+        
+        HostRef ref = mock(HostRef.class);        
+        when(vm.getAgent()).thenReturn(ref);
+        when(vm.getIdString()).thenReturn("123456");
+
+        AgentInformation info = mock(AgentInformation.class);
+        when(info.getConfigListenAddress()).thenReturn("0.0.42.42:42");
+        
+        when(agentDAO.getAgentInformation(ref)).thenReturn(info);
+        
+        queue = mock(RequestQueue.class);
+    }
+    
+    @Test
+    public void testSendGCRequestToAgent() {
+        
+        final boolean [] results = new boolean [3];
+        gcRequest = new GCRequest(queue) {
+            @Override
+            Request createRequest(InetSocketAddress target) {
+                results[0] = true;
+                if (target.getHostString().equals("0.0.42.42")) {
+                    results[1] = true;
+                }
+                if (target.getPort() == 42) {
+                    results[2] = true;
+                }
+                
+                return request;
+            }
+        };
+        
+        gcRequest.sendGCRequestToAgent(vm, agentDAO);
+        verify(vm).getAgent();
+        verify(vm).getIdString();
+        
+        assertTrue(results[0]);
+        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_ID, "123456");
+        
+        verify(queue).putRequest(request);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gc/remote-collector-client-swing/pom.xml	Sat Oct 27 11:28:19 2012 +0200
@@ -0,0 +1,148 @@
+<?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-gc</artifactId>
+    <version>0.5.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>thermostat-gc-remote-collector-client-swing</artifactId>
+  <packaging>bundle</packaging>
+
+  <name>Thermostat GC Plugin Swing Client</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-client-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-client-swing</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>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.easytesting</groupId>
+      <artifactId>fest-swing</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>net.java.openjdk.cacio</groupId>
+      <artifactId>cacio-tta</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.powermock</groupId>
+      <artifactId>powermock-api-mockito</artifactId>
+      <scope>test</scope>
+    </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.gc.remote.client.swing</Bundle-SymbolicName>
+            <Export-Package>
+              com.redhat.thermostat.gc.remote.client.swing,
+            </Export-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/gc/remote-collector-client-swing/src/main/java/com/redhat/thermostat/gc/remote/client/swing/ToolbarGCButton.java	Sat Oct 27 11:28:19 2012 +0200
@@ -0,0 +1,82 @@
+/*
+ * 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.gc.remote.client.swing;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.ImageIcon;
+
+import com.redhat.thermostat.client.swing.components.ActionButton;
+import com.redhat.thermostat.common.locale.Translate;
+
+import com.redhat.thermostat.gc.remote.client.common.IconResources;
+import com.redhat.thermostat.gc.remote.client.common.LocaleResources;
+import com.redhat.thermostat.gc.remote.client.common.RequestGCAction;
+
+@SuppressWarnings("serial")
+public class ToolbarGCButton extends ActionButton {
+
+    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
+    
+    private RequestGCAction action;
+    public ToolbarGCButton(RequestGCAction action) {
+        this(action, translator.localize(LocaleResources.PERFORM_GC));
+    }
+    
+    private ToolbarGCButton(RequestGCAction action, String text) {
+        super(new ImageIcon(IconResources.getGCIconSmall().getData().array()), text);
+        
+        setToolTipText(text);
+        this.action = action;
+        
+        addActionListener(new ToolbarGCButtonActionlistener());
+    }
+    
+    private class ToolbarGCButtonActionlistener implements ActionListener {
+        @Override
+        public void actionPerformed(ActionEvent e) {            
+            Thread actionThread = new Thread(new Runnable() {
+                @Override
+                public void run() {
+                    action.requestGC();
+                }
+            }, "ToolbarGCButton.ToolbarGCButtonActionlistener.RequestGCAction");
+            actionThread.start();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gc/remote-collector-client-swing/src/test/java/com/redhat/thermostat/gc/remote/client/swing/ToolbarGCButtonTest.java	Sat Oct 27 11:28:19 2012 +0200
@@ -0,0 +1,131 @@
+/*
+ * 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.gc.remote.client.swing;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import java.awt.Dimension;
+import java.util.prefs.BackingStoreException;
+import java.util.prefs.Preferences;
+
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+
+import net.java.openjdk.cacio.ctc.junit.CacioFESTRunner;
+
+import org.fest.swing.edt.FailOnThreadViolationRepaintManager;
+import org.fest.swing.edt.GuiActionRunner;
+import org.fest.swing.edt.GuiTask;
+import org.fest.swing.fixture.FrameFixture;
+import org.fest.swing.fixture.JButtonFixture;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import com.redhat.thermostat.client.swing.components.HeaderPanel;
+import com.redhat.thermostat.gc.remote.client.common.RequestGCAction;
+
+@RunWith(CacioFESTRunner.class)
+public class ToolbarGCButtonTest {
+
+    private JFrame frame;
+    private FrameFixture frameFixture;
+    private ToolbarGCButton gcButton;
+        
+    private RequestGCAction action;
+    
+    @BeforeClass
+    public static void setUpOnce() {
+        FailOnThreadViolationRepaintManager.install();
+    }
+    
+    @Before
+    public void setUp() {
+        
+        final Preferences prefs = mock(Preferences.class);
+        
+        action = mock(RequestGCAction.class);
+        
+        GuiActionRunner.execute(new GuiTask() {
+            @Override
+            protected void executeInEDT() throws Throwable {
+                frame = new JFrame();
+                
+                HeaderPanel header = new HeaderPanel(prefs, "Test Panel");
+                header.setName("headerPanel");
+                
+                JPanel content = new JPanel();
+                content.setName("contentPanel");
+                
+                header.setContent(content);
+               
+                gcButton = new ToolbarGCButton(action);
+                gcButton.setName("gcButton");
+                header.addToolBarButton(gcButton);
+                
+                frame.getContentPane().add(header);
+                
+                frame.setMinimumSize(new Dimension(800, 300));
+            }
+        });
+        frameFixture = new FrameFixture(frame);
+    }
+    
+    @After
+    public void tearDown() throws BackingStoreException {
+        frameFixture.cleanUp();
+        frameFixture = null;
+    }
+    
+    @Test
+    public void testEventDelivered() throws InterruptedException {
+        frameFixture.show();
+        
+        JButtonFixture button = frameFixture.button("gcButton");
+        button.requireVisible();
+        
+        button.click();
+        
+        // timing dependent test...
+        Thread.sleep(250);
+        
+        verify(action).requestGC();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gc/remote-collector-command/pom.xml	Sat Oct 27 11:28:19 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-gc</artifactId>
+    <version>0.5.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>thermostat-gc-remote-collector-command</artifactId>
+  <packaging>bundle</packaging>
+
+  <name>Thermostat GC Plugin Command Channel</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-gc-remote-collector-common</artifactId>
+      <version>${project.version}</version>      
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-agent-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.gc.remote.command</Bundle-SymbolicName>
+            <Bundle-Activator>com.redhat.thermostat.gc.remote.command.osgi.GCCommandReceiverActivator</Bundle-Activator>            
+            <Export-Package>
+              com.redhat.thermostat.gc.remote.command,
+            </Export-Package>
+            <Private-Package>
+                com.redhat.thermostat.gc.remote.command.osgi,
+                com.redhat.thermostat.gc.remote.command.internal,
+            </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/gc/remote-collector-command/src/main/java/com/redhat/thermostat/gc/remote/command/GCCommandReceiver.java	Sat Oct 27 11:28:19 2012 +0200
@@ -0,0 +1,65 @@
+/*
+ * 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.gc.remote.command;
+
+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.gc.remote.command.internal.GC;
+import com.redhat.thermostat.gc.remote.common.command.GCCommand;
+import com.redhat.thermostat.utils.management.MXBeanConnector;
+
+public class GCCommandReceiver implements RequestReceiver {
+
+    @Override
+    public Response receive(Request request) {
+        
+        String command = request.getParameter(GCCommand.class.getName());
+        switch (GCCommand.valueOf(command)) {
+        case REQUEST_GC:
+            String vmId = request.getParameter(GCCommand.VM_ID);
+            MXBeanConnector connector = new MXBeanConnector(vmId);
+            new GC(connector).gc();
+            break;
+        
+        default:
+            break;
+        }
+        return new Response(ResponseType.OK);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gc/remote-collector-command/src/main/java/com/redhat/thermostat/gc/remote/command/internal/GC.java	Sat Oct 27 11:28:19 2012 +0200
@@ -0,0 +1,92 @@
+/*
+ * 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.gc.remote.command.internal;
+
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryMXBean;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.redhat.thermostat.utils.management.MXBeanConnection;
+import com.redhat.thermostat.utils.management.MXBeanConnector;
+
+public class GC {
+
+    private static final Logger logger = Logger.getLogger(GC.class.getSimpleName());
+
+    private MXBeanConnector connector;
+    public GC(MXBeanConnector connector) {
+        this.connector = connector;
+    }
+    
+    public void gc() {
+        boolean closeAfter = false;
+        if (!connector.isAttached()) {
+            closeAfter = true; 
+            try {
+                connector.attach();
+
+            } catch (Exception ex) {
+                logger.log(Level.SEVERE, "can't attach", ex);
+                if (closeAfter) {
+                    closeConnection();
+                }
+            }
+        }
+        
+        try (MXBeanConnection connection = connector.connect()) {
+
+            MemoryMXBean bean = connection.createProxy(ManagementFactory.MEMORY_MXBEAN_NAME, MemoryMXBean.class);
+            bean.gc();
+
+        } catch (Exception ex) {
+            logger.log(Level.SEVERE, "can't get MXBeanConnection connection", ex);
+        }
+        
+        if (closeAfter) {
+            closeConnection();
+        }
+    }
+    
+    private void closeConnection() {
+        try {
+            connector.close();
+        } catch (Exception ex) {
+            logger.log(Level.SEVERE, "can't close connection to vm", ex);
+        }
+    }    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gc/remote-collector-command/src/main/java/com/redhat/thermostat/gc/remote/command/osgi/GCCommandReceiverActivator.java	Sat Oct 27 11:28:19 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.gc.remote.command.osgi;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+import com.redhat.thermostat.agent.command.ReceiverRegistry;
+import com.redhat.thermostat.gc.remote.command.GCCommandReceiver;
+
+public class GCCommandReceiverActivator implements BundleActivator {
+
+    @Override
+    public void start(BundleContext context) throws Exception {
+        ReceiverRegistry registry = new ReceiverRegistry(context);
+        registry.registerReceiver(new GCCommandReceiver());
+    }
+    
+    @Override
+    public void stop(BundleContext context) throws Exception {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gc/remote-collector-common/pom.xml	Sat Oct 27 11:28:19 2012 +0200
@@ -0,0 +1,122 @@
+<?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-gc</artifactId>
+    <version>0.5.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>thermostat-gc-remote-collector-common</artifactId>
+  <packaging>bundle</packaging>
+
+  <name>Thermostat GC Plugin Common Client API</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-client-command</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-client-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.gc.remote.common.command</Bundle-SymbolicName>
+            <Export-Package>
+                com.redhat.thermostat.gc.remote.common.command
+            </Export-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/gc/remote-collector-common/src/main/java/com/redhat/thermostat/gc/remote/common/command/GCCommand.java	Sat Oct 27 11:28:19 2012 +0200
@@ -0,0 +1,45 @@
+/*
+ * 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.gc.remote.common.command;
+
+public enum GCCommand {
+
+    REQUEST_GC;
+    
+    public static final String VM_ID = "VM_ID";
+    public static final String RECEIVER = "com.redhat.thermostat.gc.remote.command.GCCommandReceiver";
+}
Binary file gc/remote-collector-common/src/main/resources/com/redhat/thermostat/gc/remote/client/common/gcSmall.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gc/remote-collector-common/src/main/resources/com/redhat/thermostat/gc/remote/client/common/strings.properties	Sat Oct 27 11:28:19 2012 +0200
@@ -0,0 +1,1 @@
+PERFORM_GC = Perform GC
\ No newline at end of file
--- a/pom.xml	Fri Oct 26 15:59:28 2012 +0200
+++ b/pom.xml	Sat Oct 27 11:28:19 2012 +0200
@@ -126,6 +126,7 @@
     <module>killvm</module>
     <module>web</module>
     <module>system-backend</module>
+    <module>gc</module>
   </modules>
 
   <build>
--- a/thread/client-common/src/main/java/com/redhat/thermostat/thread/client/common/IconResources.java	Fri Oct 26 15:59:28 2012 +0200
+++ b/thread/client-common/src/main/java/com/redhat/thermostat/thread/client/common/IconResources.java	Sat Oct 27 11:28:19 2012 +0200
@@ -36,39 +36,24 @@
 
 package com.redhat.thermostat.thread.client.common;
 
-import java.io.IOException;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
 import com.redhat.thermostat.client.ui.IconDescriptor;
 
 public class IconResources {
 
-    private static final Logger logger = Logger.getLogger(IconResources.class.getSimpleName());
-
     private static IconDescriptor monitor;
     private static IconDescriptor record;
 
     public static IconDescriptor getMonitorIcon() {
         if (monitor == null) {
-            monitor = loadIcon("com/redhat/thermostat/thread/client/common/monitor.png");
+            monitor = IconDescriptor.loadIcon("com/redhat/thermostat/thread/client/common/monitor.png");
         }
         return monitor;
     }
     
     public static IconDescriptor getRecordIcon() {
         if (record == null) {
-            record = loadIcon("com/redhat/thermostat/thread/client/common/gtk-media-record.png");
+            record = IconDescriptor.loadIcon("com/redhat/thermostat/thread/client/common/gtk-media-record.png");
         }
         return record;
     }
-    
-    private static IconDescriptor loadIcon(String name) {
-        try {
-            return IconDescriptor.createFromClassloader(ClassLoader.getSystemClassLoader(), name);
-        } catch (IOException e) {
-            logger.log(Level.WARNING, "Can't load " + name, e);
-        }
-        return null;
-    }
 }
--- a/thread/collector/src/main/java/com/redhat/thermostat/thread/collector/HarvesterCommand.java	Fri Oct 26 15:59:28 2012 +0200
+++ b/thread/collector/src/main/java/com/redhat/thermostat/thread/collector/HarvesterCommand.java	Sat Oct 27 11:28:19 2012 +0200
@@ -1,3 +1,39 @@
+/*
+ * 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.thread.collector;
 
 public enum HarvesterCommand {
--- a/thread/harvester/pom.xml	Fri Oct 26 15:59:28 2012 +0200
+++ b/thread/harvester/pom.xml	Sat Oct 27 11:28:19 2012 +0200
@@ -78,6 +78,12 @@
       <scope>provided</scope>
     </dependency>
 
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-agent-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    
   </dependencies>
 
   <build>
@@ -93,7 +99,6 @@
             <Bundle-SymbolicName>com.redhat.thermostat.thread.harvester</Bundle-SymbolicName>
             <Private-Package>
               com.redhat.thermostat.thread.harvester,
-              com.redhat.thermostat.thread.harvester.management,
               com.redhat.thermostat.thread.harvester.osgi,
             </Private-Package>
             <!-- Do not autogenerate uses clauses in Manifests -->
--- a/thread/harvester/src/main/java/com/redhat/thermostat/thread/harvester/Harvester.java	Fri Oct 26 15:59:28 2012 +0200
+++ b/thread/harvester/src/main/java/com/redhat/thermostat/thread/harvester/Harvester.java	Sat Oct 27 11:28:19 2012 +0200
@@ -51,11 +51,12 @@
 import javax.management.MalformedObjectNameException;
 
 import com.redhat.thermostat.thread.dao.ThreadDao;
-import com.redhat.thermostat.thread.harvester.management.MXBeanConnection;
-import com.redhat.thermostat.thread.harvester.management.MXBeanConnector;
+
 import com.redhat.thermostat.thread.model.ThreadInfoData;
 import com.redhat.thermostat.thread.model.ThreadSummary;
 import com.redhat.thermostat.thread.model.VMThreadCapabilities;
+import com.redhat.thermostat.utils.management.MXBeanConnection;
+import com.redhat.thermostat.utils.management.MXBeanConnector;
 
 @SuppressWarnings("restriction")
 class Harvester {
--- a/thread/harvester/src/main/java/com/redhat/thermostat/thread/harvester/management/MXBeanConnection.java	Fri Oct 26 15:59:28 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +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.thread.harvester.management;
-
-import java.io.Closeable;
-import java.io.IOException;
-
-import javax.management.JMX;
-import javax.management.MBeanServerConnection;
-import javax.management.MalformedObjectNameException;
-import javax.management.ObjectName;
-import javax.management.remote.JMXConnector;
-
-public class MXBeanConnection implements Closeable {
-
-    private JMXConnector connection;
-    private MBeanServerConnection mbsc;
-    
-    MXBeanConnection(JMXConnector connection, MBeanServerConnection mbsc) {
-        this.connection = connection;
-        this.mbsc = mbsc;
-    }
-    
-    public synchronized <E> E createProxy(String name, Class<? extends E> proxyClass) throws MalformedObjectNameException {
-        ObjectName objectName = new ObjectName(name);
-        return JMX.newMXBeanProxy(mbsc, objectName, proxyClass);
-    }
-    
-    @Override
-    public void close() throws IOException {
-        connection.close();
-    }
-}
--- a/thread/harvester/src/main/java/com/redhat/thermostat/thread/harvester/management/MXBeanConnector.java	Fri Oct 26 15:59:28 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,121 +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.thread.harvester.management;
-
-import java.io.Closeable;
-import java.io.File;
-import java.io.IOException;
-import java.util.Properties;
-
-import javax.management.MBeanServerConnection;
-import javax.management.remote.JMXConnector;
-import javax.management.remote.JMXConnectorFactory;
-import javax.management.remote.JMXServiceURL;
-
-import com.redhat.thermostat.common.dao.VmRef;
-import com.sun.tools.attach.VirtualMachine;
-
-public class MXBeanConnector implements Closeable {
-
-    private static final String CONNECTOR_ADDRESS_PROPERTY = "com.sun.management.jmxremote.localConnectorAddress";
-    private String connectorAddress;
-    
-    private VirtualMachine vm;
-    
-    private boolean attached;
-    
-    private String reference;
-    
-    public MXBeanConnector(String reference) {
-        this.reference = reference;
-    }
-    
-    public MXBeanConnector(VmRef reference) {
-        this.reference = reference.getStringID();
-    }
-    
-    public synchronized void attach() throws Exception {
-        if (attached)
-            throw new IOException("Already attached");
-        
-        vm = VirtualMachine.attach(reference);
-        attached = true;
-        
-        Properties props = vm.getAgentProperties();
-        connectorAddress = props.getProperty(CONNECTOR_ADDRESS_PROPERTY);
-        if (connectorAddress == null) {
-           props = vm.getSystemProperties();
-           String home = props.getProperty("java.home");
-           String agent = home + File.separator + "lib" + File.separator + "management-agent.jar";
-           vm.loadAgent(agent);
-           
-           props = vm.getAgentProperties();
-           connectorAddress = props.getProperty(CONNECTOR_ADDRESS_PROPERTY);
-        }
-    }
-    
-    public synchronized MXBeanConnection connect() throws Exception {
-        
-        if (!attached)
-            throw new IOException("Agent not attached to target VM");
-        
-        JMXServiceURL url = new JMXServiceURL(connectorAddress);
-        JMXConnector connection = JMXConnectorFactory.connect(url);
-        MBeanServerConnection mbsc = null;
-        try {
-            mbsc = connection.getMBeanServerConnection();
-            
-        } catch (IOException e) {
-            connection.close();
-            throw e;
-        }
-        
-        return new MXBeanConnection(connection, mbsc);
-    }
-    
-    public boolean isAttached() {
-        return attached;
-    }
-    
-    @Override
-    public synchronized void close() throws IOException {
-        if (attached) {
-            vm.detach();
-            attached = false;
-        }
-    }
-}
--- a/thread/harvester/src/test/java/com/redhat/thermostat/thread/harvester/HarvesterTest.java	Fri Oct 26 15:59:28 2012 +0200
+++ b/thread/harvester/src/test/java/com/redhat/thermostat/thread/harvester/HarvesterTest.java	Sat Oct 27 11:28:19 2012 +0200
@@ -61,11 +61,12 @@
 import org.mockito.ArgumentCaptor;
 
 import com.redhat.thermostat.thread.dao.ThreadDao;
-import com.redhat.thermostat.thread.harvester.management.MXBeanConnection;
-import com.redhat.thermostat.thread.harvester.management.MXBeanConnector;
+
 import com.redhat.thermostat.thread.model.ThreadInfoData;
 import com.redhat.thermostat.thread.model.ThreadSummary;
 import com.redhat.thermostat.thread.model.VMThreadCapabilities;
+import com.redhat.thermostat.utils.management.MXBeanConnection;
+import com.redhat.thermostat.utils.management.MXBeanConnector;
 
 public class HarvesterTest {