# HG changeset patch # User Elliott Baron # Date 1357591803 18000 # Node ID 0ba74f790a8a91f42fc9188403ff5e32b0b56873 # Parent 9e6bcfc40ea10c781dd101e96a4e6c2fc6eae777 Create VM Memory agent and common bundles This commit extracts VM Memory data collection from SystemBackend and related classes into a vm-memory-agent bundle. It also moves the VmMemoryStatDAO from common-core into a vm-memory-common bundle that registers the DAO once Storage is available. This also removes the DAO from DAOFactory. This also temporarily adds the vm-memory-common bundle as a dependency to client-cli until my later dynamic vm-stat patch. Reviewed-by: omajid Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2013-January/004995.html diff -r 9e6bcfc40ea1 -r 0ba74f790a8a client/cli/pom.xml --- a/client/cli/pom.xml Mon Jan 07 15:48:38 2013 -0500 +++ b/client/cli/pom.xml Mon Jan 07 15:50:03 2013 -0500 @@ -106,6 +106,12 @@ thermostat-vm-cpu-common ${project.version} + + + com.redhat.thermostat + thermostat-vm-memory-common + ${project.version} + @@ -126,7 +132,10 @@ <_nouses>true - *,com.redhat.thermostat.vm.cpu.common;resolution:=optional + + *,com.redhat.thermostat.vm.cpu.common;resolution:=optional, + com.redhat.thermostat.vm.memory.common;resolution:=optional + diff -r 9e6bcfc40ea1 -r 0ba74f790a8a client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/VMStatCommand.java --- a/client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/VMStatCommand.java Mon Jan 07 15:48:38 2013 -0500 +++ b/client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/VMStatCommand.java Mon Jan 07 15:50:03 2013 -0500 @@ -48,12 +48,12 @@ import com.redhat.thermostat.common.cli.CommandException; import com.redhat.thermostat.common.cli.HostVMArguments; import com.redhat.thermostat.common.cli.SimpleCommand; -import com.redhat.thermostat.common.dao.VmMemoryStatDAO; import com.redhat.thermostat.common.dao.VmRef; import com.redhat.thermostat.common.locale.Translate; import com.redhat.thermostat.common.utils.LoggingUtils; import com.redhat.thermostat.common.utils.OSGIUtils; import com.redhat.thermostat.vm.cpu.common.VmCpuStatDAO; +import com.redhat.thermostat.vm.memory.common.VmMemoryStatDAO; public class VMStatCommand extends SimpleCommand { diff -r 9e6bcfc40ea1 -r 0ba74f790a8a client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/VMStatPrinter.java --- a/client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/VMStatPrinter.java Mon Jan 07 15:48:38 2013 -0500 +++ b/client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/VMStatPrinter.java Mon Jan 07 15:50:03 2013 -0500 @@ -48,7 +48,6 @@ import com.redhat.thermostat.common.Size; import com.redhat.thermostat.common.cli.TableRenderer; -import com.redhat.thermostat.common.dao.VmMemoryStatDAO; import com.redhat.thermostat.common.dao.VmRef; import com.redhat.thermostat.common.locale.Translate; import com.redhat.thermostat.storage.model.TimeStampedPojo; @@ -57,6 +56,7 @@ import com.redhat.thermostat.storage.model.VmCpuStat; import com.redhat.thermostat.storage.model.VmMemoryStat; import com.redhat.thermostat.vm.cpu.common.VmCpuStatDAO; +import com.redhat.thermostat.vm.memory.common.VmMemoryStatDAO; class VMStatPrinter { diff -r 9e6bcfc40ea1 -r 0ba74f790a8a client/cli/src/test/java/com/redhat/thermostat/client/cli/internal/VmStatCommandTest.java --- a/client/cli/src/test/java/com/redhat/thermostat/client/cli/internal/VmStatCommandTest.java Mon Jan 07 15:48:38 2013 -0500 +++ b/client/cli/src/test/java/com/redhat/thermostat/client/cli/internal/VmStatCommandTest.java Mon Jan 07 15:50:03 2013 -0500 @@ -64,7 +64,6 @@ import com.redhat.thermostat.common.cli.CommandException; import com.redhat.thermostat.common.cli.SimpleArguments; import com.redhat.thermostat.common.dao.HostRef; -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.storage.model.VmCpuStat; @@ -74,6 +73,7 @@ import com.redhat.thermostat.test.TestCommandContextFactory; import com.redhat.thermostat.test.TestTimerFactory; import com.redhat.thermostat.vm.cpu.common.VmCpuStatDAO; +import com.redhat.thermostat.vm.memory.common.VmMemoryStatDAO; public class VmStatCommandTest { diff -r 9e6bcfc40ea1 -r 0ba74f790a8a common/core/src/main/java/com/redhat/thermostat/common/dao/DAOFactory.java --- a/common/core/src/main/java/com/redhat/thermostat/common/dao/DAOFactory.java Mon Jan 07 15:48:38 2013 -0500 +++ b/common/core/src/main/java/com/redhat/thermostat/common/dao/DAOFactory.java Mon Jan 07 15:50:03 2013 -0500 @@ -56,8 +56,6 @@ public VmInfoDAO getVmInfoDAO(); - public VmMemoryStatDAO getVmMemoryStatDAO(); - public VmClassStatDAO getVmClassStatsDAO(); public VmGcStatDAO getVmGcStatDAO(); diff -r 9e6bcfc40ea1 -r 0ba74f790a8a common/core/src/main/java/com/redhat/thermostat/common/dao/DAOFactoryImpl.java --- a/common/core/src/main/java/com/redhat/thermostat/common/dao/DAOFactoryImpl.java Mon Jan 07 15:48:38 2013 -0500 +++ b/common/core/src/main/java/com/redhat/thermostat/common/dao/DAOFactoryImpl.java Mon Jan 07 15:50:03 2013 -0500 @@ -60,7 +60,6 @@ private NetworkInterfaceInfoDAO networkInfoDAO; private VmInfoDAO vmInfoDAO; private VmClassStatDAO vmClassStatDAO; - private VmMemoryStatDAO vmMemStatDAO; private VmGcStatDAO vmGcStatDAO; public DAOFactoryImpl(StorageProvider prov) { @@ -108,12 +107,6 @@ } @Override - public VmMemoryStatDAO getVmMemoryStatDAO() { - ensureStorageConnected(); - return vmMemStatDAO; - } - - @Override public VmClassStatDAO getVmClassStatsDAO() { ensureStorageConnected(); return vmClassStatDAO; @@ -151,7 +144,6 @@ registerAndRecordService(VmInfoDAO.class, getVmInfoDAO()); registerAndRecordService(VmClassStatDAO.class, getVmClassStatsDAO()); registerAndRecordService(VmGcStatDAO.class, getVmGcStatDAO()); - registerAndRecordService(VmMemoryStatDAO.class, getVmMemoryStatDAO()); } /* @@ -164,7 +156,6 @@ networkInfoDAO = new NetworkInterfaceInfoDAOImpl(storage); vmInfoDAO = new VmInfoDAOImpl(storage); vmClassStatDAO = new VmClassStatDAOImpl(storage); - vmMemStatDAO = new VmMemoryStatDAOImpl(storage); vmGcStatDAO = new VmGcStatDAOImpl(storage); } diff -r 9e6bcfc40ea1 -r 0ba74f790a8a common/core/src/main/java/com/redhat/thermostat/common/dao/VmMemoryStatDAO.java --- a/common/core/src/main/java/com/redhat/thermostat/common/dao/VmMemoryStatDAO.java Mon Jan 07 15:48:38 2013 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,59 +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 - * . - * - * 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.common.dao; - -import java.util.List; - -import com.redhat.thermostat.storage.core.Category; -import com.redhat.thermostat.storage.core.Key; -import com.redhat.thermostat.storage.model.VmMemoryStat; -import com.redhat.thermostat.storage.model.VmMemoryStat.Generation; - -public interface VmMemoryStatDAO { - - static final Key generationsKey = new Key<>("generations", false); - - static final Category vmMemoryStatsCategory = new Category("vm-memory-stats", - Key.AGENT_ID, Key.VM_ID, Key.TIMESTAMP, generationsKey); - - public VmMemoryStat getLatestMemoryStat(VmRef ref); - - public List getLatestVmMemoryStats(VmRef vm, long since); - - public void putVmMemoryStat(VmMemoryStat stat); - -} diff -r 9e6bcfc40ea1 -r 0ba74f790a8a common/core/src/main/java/com/redhat/thermostat/common/dao/VmMemoryStatDAOImpl.java --- a/common/core/src/main/java/com/redhat/thermostat/common/dao/VmMemoryStatDAOImpl.java Mon Jan 07 15:48:38 2013 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,84 +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 - * . - * - * 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.common.dao; - -import java.util.List; - -import com.redhat.thermostat.storage.core.Cursor; -import com.redhat.thermostat.storage.core.Key; -import com.redhat.thermostat.storage.core.Query; -import com.redhat.thermostat.storage.core.Storage; -import com.redhat.thermostat.storage.core.Query.Criteria; -import com.redhat.thermostat.storage.model.VmMemoryStat; - -class VmMemoryStatDAOImpl implements VmMemoryStatDAO { - - private final Storage storage; - private final VmLatestPojoListGetter getter; - - VmMemoryStatDAOImpl(Storage storage) { - this.storage = storage; - storage.registerCategory(vmMemoryStatsCategory); - getter = new VmLatestPojoListGetter<>(storage, vmMemoryStatsCategory, VmMemoryStat.class); - } - - @Override - public VmMemoryStat getLatestMemoryStat(VmRef ref) { - Query query = storage.createQuery() - .from(vmMemoryStatsCategory) - .where(Key.AGENT_ID, Criteria.EQUALS, ref.getAgent().getAgentId()) - .where(Key.VM_ID, Criteria.EQUALS, ref.getId()) - .sort(Key.TIMESTAMP, Query.SortDirection.DESCENDING) - .limit(1); - Cursor cursor = storage.findAllPojos(query, VmMemoryStat.class); - if (cursor.hasNext()) { - return cursor.next(); - } - return null; - } - - @Override - public void putVmMemoryStat(VmMemoryStat stat) { - storage.putPojo(vmMemoryStatsCategory, false, stat); - } - - @Override - public List getLatestVmMemoryStats(VmRef ref, long since) { - return getter.getLatest(ref, since); - } - -} diff -r 9e6bcfc40ea1 -r 0ba74f790a8a common/core/src/test/java/com/redhat/thermostat/common/dao/MongoDAOFactoryTest.java --- a/common/core/src/test/java/com/redhat/thermostat/common/dao/MongoDAOFactoryTest.java Mon Jan 07 15:48:38 2013 -0500 +++ b/common/core/src/test/java/com/redhat/thermostat/common/dao/MongoDAOFactoryTest.java Mon Jan 07 15:50:03 2013 -0500 @@ -108,12 +108,6 @@ } @Test - public void testGetVmMemoryStatDAO() { - VmMemoryStatDAO dao = daoFactory.getVmMemoryStatDAO(); - assertNotNull(dao); - } - - @Test public void testGetHostInfoDAO() { HostInfoDAO dao = daoFactory.getHostInfoDAO(); assertNotNull(dao); @@ -131,8 +125,8 @@ daoFactory.registerDAOsAndStorageAsOSGiServices(); - // currently 9 DAOs and Storage are registered - assertEquals(9, bundleContext.getAllServices().size()); + // currently 8 DAOs and Storage are registered + assertEquals(8, bundleContext.getAllServices().size()); } @Test diff -r 9e6bcfc40ea1 -r 0ba74f790a8a common/core/src/test/java/com/redhat/thermostat/common/dao/VmMemoryStatDAOTest.java --- a/common/core/src/test/java/com/redhat/thermostat/common/dao/VmMemoryStatDAOTest.java Mon Jan 07 15:48:38 2013 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,198 +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 - * . - * - * 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.common.dao; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.same; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.redhat.thermostat.storage.core.Cursor; -import com.redhat.thermostat.storage.core.Key; -import com.redhat.thermostat.storage.core.Query; -import com.redhat.thermostat.storage.core.Storage; -import com.redhat.thermostat.storage.core.Query.Criteria; -import com.redhat.thermostat.storage.model.VmMemoryStat; -import com.redhat.thermostat.storage.model.VmMemoryStat.Generation; -import com.redhat.thermostat.storage.model.VmMemoryStat.Space; -import com.redhat.thermostat.test.MockQuery; - -public class VmMemoryStatDAOTest { - - private static final int VM_ID = 0xcafe; - private static final String AGENT_ID = "agent"; - - private Storage storage; - private VmRef vmRef; - - private MockQuery query; - private Cursor cursor; - - @SuppressWarnings("unchecked") - @Before - public void setUp() { - - - HostRef hostRef = mock(HostRef.class); - when(hostRef.getAgentId()).thenReturn(AGENT_ID); - - vmRef = mock(VmRef.class); - when(vmRef.getAgent()).thenReturn(hostRef); - when(vmRef.getId()).thenReturn(VM_ID); - - storage = mock(Storage.class); - query = new MockQuery(); - when(storage.createQuery()).thenReturn(query); - - cursor = mock(Cursor.class); - when(storage.findAllPojos(any(Query.class), same(VmMemoryStat.class))).thenReturn(cursor); - - when(cursor.hasNext()).thenReturn(false); - - } - - @After - public void tearDown() { - query = null; - vmRef = null; - cursor = null; - storage = null; - } - - @Test - public void testCategories() { - Collection> keys; - - assertEquals("vm-memory-stats", VmMemoryStatDAO.vmMemoryStatsCategory.getName()); - keys = VmMemoryStatDAO.vmMemoryStatsCategory.getKeys(); - assertTrue(keys.contains(new Key<>("agentId", true))); - assertTrue(keys.contains(new Key("vmId", true))); - assertTrue(keys.contains(new Key("timeStamp", false))); - assertTrue(keys.contains(new Key("generations", false))); - assertEquals(4, keys.size()); - } - - @Test - public void testGetLatest() { - VmMemoryStatDAO impl = new VmMemoryStatDAOImpl(storage); - impl.getLatestMemoryStat(vmRef); - - verifyQuery(); - } - - @Test - public void testGetLatestSince() { - VmMemoryStatDAO impl = new VmMemoryStatDAOImpl(storage); - impl.getLatestVmMemoryStats(vmRef, 123); - - verifyQuery(); - - assertTrue(query.hasWhereClause(Key.TIMESTAMP, Criteria.GREATER_THAN, 123l)); - } - - private void verifyQuery() { - - assertTrue(query.hasWhereClause(Key.AGENT_ID, Criteria.EQUALS, AGENT_ID)); - assertTrue(query.hasWhereClause(Key.VM_ID, Criteria.EQUALS, VM_ID)); - assertTrue(query.hasSort(Key.TIMESTAMP, Query.SortDirection.DESCENDING)); - } - - @Test - public void testGetLatestReturnsNullWhenStorageEmpty() { - when(cursor.hasNext()).thenReturn(false); - when(cursor.next()).thenReturn(null); - - Storage storage = mock(Storage.class); - when(storage.createQuery()).thenReturn(new MockQuery()); - when(storage.findAllPojos(any(Query.class), same(VmMemoryStat.class))).thenReturn(cursor); - - VmMemoryStatDAO impl = new VmMemoryStatDAOImpl(storage); - VmMemoryStat latest = impl.getLatestMemoryStat(vmRef); - assertTrue(latest == null); - } - - @Test - public void testPutVmMemoryStat() { - - List generations = new ArrayList(); - - int i = 0; - for (String genName: new String[] { "new", "old", "perm" }) { - Generation gen = new Generation(); - gen.setName(genName); - gen.setCollector(gen.getName()); - generations.add(gen); - List spaces = new ArrayList(); - String[] spaceNames = null; - if (genName.equals("new")) { - spaceNames = new String[] { "eden", "s0", "s1" }; - } else if (genName.equals("old")) { - spaceNames = new String[] { "old" }; - } else { - spaceNames = new String[] { "perm" }; - } - for (String spaceName: spaceNames) { - Space space = new Space(); - space.setName(spaceName); - space.setIndex(0); - space.setUsed(i++); - space.setCapacity(i++); - space.setMaxCapacity(i++); - spaces.add(space); - } - gen.setSpaces(spaces.toArray(new Space[spaces.size()])); - } - VmMemoryStat stat = new VmMemoryStat(1, 2, generations.toArray(new Generation[generations.size()])); - - Storage storage = mock(Storage.class); - VmMemoryStatDAO dao = new VmMemoryStatDAOImpl(storage); - dao.putVmMemoryStat(stat); - - verify(storage).putPojo(VmMemoryStatDAO.vmMemoryStatsCategory, false, stat); - } -} diff -r 9e6bcfc40ea1 -r 0ba74f790a8a distribution/config/commands/agent.properties --- a/distribution/config/commands/agent.properties Mon Jan 07 15:48:38 2013 -0500 +++ b/distribution/config/commands/agent.properties Mon Jan 07 15:50:03 2013 -0500 @@ -15,6 +15,8 @@ thermostat-host-memory-agent-@project.version@.jar, \ thermostat-vm-cpu-common-@project.version@.jar, \ thermostat-vm-cpu-agent-@project.version@.jar, \ + thermostat-vm-memory-common-@project.version@.jar, \ + thermostat-vm-memory-agent-@project.version@.jar, \ thermostat-vm-heap-analysis-common-@project.version@.jar, \ thermostat-vm-heap-analysis-agent-@project.version@.jar, \ thermostat-killvm-agent-@project.version@.jar, \ diff -r 9e6bcfc40ea1 -r 0ba74f790a8a distribution/config/commands/gui.properties --- a/distribution/config/commands/gui.properties Mon Jan 07 15:48:38 2013 -0500 +++ b/distribution/config/commands/gui.properties Mon Jan 07 15:50:03 2013 -0500 @@ -27,6 +27,7 @@ thermostat-vm-cpu-client-swing-@project.version@.jar, \ thermostat-vm-gc-client-core-@project.version@.jar, \ thermostat-vm-gc-client-swing-@project.version@.jar, \ + thermostat-vm-memory-common-@project.version@.jar, \ thermostat-vm-memory-client-core-@project.version@.jar, \ thermostat-vm-memory-client-swing-@project.version@.jar, \ thermostat-vm-heap-analysis-client-core-@project.version@.jar, \ diff -r 9e6bcfc40ea1 -r 0ba74f790a8a distribution/config/commands/vm-stat.properties --- a/distribution/config/commands/vm-stat.properties Mon Jan 07 15:48:38 2013 -0500 +++ b/distribution/config/commands/vm-stat.properties Mon Jan 07 15:50:03 2013 -0500 @@ -1,5 +1,6 @@ bundles = thermostat-client-cli-${project.version}.jar, \ thermostat-vm-cpu-common-${project.version}.jar, \ + thermostat-vm-memory-common-${project.version}.jar, \ thermostat-storage-mongodb-${project.version}.jar, \ thermostat-web-common-${project.version}.jar, \ thermostat-web-client-${project.version}.jar, \ diff -r 9e6bcfc40ea1 -r 0ba74f790a8a distribution/pom.xml --- a/distribution/pom.xml Mon Jan 07 15:48:38 2013 -0500 +++ b/distribution/pom.xml Mon Jan 07 15:50:03 2013 -0500 @@ -437,6 +437,11 @@ com.redhat.thermostat + thermostat-vm-memory-agent + ${project.version} + + + com.redhat.thermostat thermostat-vm-heap-analysis-client-swing ${project.version} diff -r 9e6bcfc40ea1 -r 0ba74f790a8a eclipse/com.redhat.thermostat.client.feature/feature.xml --- a/eclipse/com.redhat.thermostat.client.feature/feature.xml Mon Jan 07 15:48:38 2013 -0500 +++ b/eclipse/com.redhat.thermostat.client.feature/feature.xml Mon Jan 07 15:50:03 2013 -0500 @@ -203,4 +203,11 @@ version="0.0.0" unpack="false"/> + + diff -r 9e6bcfc40ea1 -r 0ba74f790a8a eclipse/com.redhat.thermostat.client.feature/pom.xml --- a/eclipse/com.redhat.thermostat.client.feature/pom.xml Mon Jan 07 15:48:38 2013 -0500 +++ b/eclipse/com.redhat.thermostat.client.feature/pom.xml Mon Jan 07 15:50:03 2013 -0500 @@ -41,6 +41,11 @@ com.redhat.thermostat + thermostat-vm-memory-client-core + 0.5.0-SNAPSHOT + + + com.redhat.thermostat thermostat-vm-gc-client-core 0.5.0-SNAPSHOT diff -r 9e6bcfc40ea1 -r 0ba74f790a8a system-backend/src/main/java/com/redhat/thermostat/backend/system/JvmStatDataExtractor.java --- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/JvmStatDataExtractor.java Mon Jan 07 15:48:38 2013 -0500 +++ b/system-backend/src/main/java/com/redhat/thermostat/backend/system/JvmStatDataExtractor.java Mon Jan 07 15:50:03 2013 -0500 @@ -36,9 +36,6 @@ package com.redhat.thermostat.backend.system; -import com.redhat.thermostat.storage.model.VmMemoryStat.Generation; - -import sun.jvmstat.monitor.Monitor; import sun.jvmstat.monitor.MonitorException; import sun.jvmstat.monitor.MonitoredVm; import sun.jvmstat.monitor.MonitoredVmUtil; @@ -117,52 +114,6 @@ return (Long) vm.findByName("sun.gc.collector." + collector + ".invocations").getValue(); } - public long getTotalGcGenerations() throws MonitorException { - return (Long) vm.findByName("sun.gc.policy.generations").getValue(); - } - - public String getGenerationName(long generation) throws MonitorException { - return (String) vm.findByName("sun.gc.generation." + generation + ".name").getValue(); - } - - public long getGenerationCapacity(long generation) throws MonitorException { - return (Long) vm.findByName("sun.gc.generation." + generation + ".capacity").getValue(); - } - - public long getGenerationMaxCapacity(long generation) throws MonitorException { - return (Long) vm.findByName("sun.gc.generation." + generation + ".maxCapacity").getValue(); - } - - public String getGenerationCollector(long generation) throws MonitorException { - // this is just re-implementing getCollectorName() - // TODO check generation number and collector number are always associated - Monitor m = vm.findByName("sun.gc.collector." + generation + ".name"); - if (m == null) { - return Generation.COLLECTOR_NONE; - } - return (String) m.getValue(); - } - - public long getTotalSpaces(long generation) throws MonitorException { - return (Long) vm.findByName("sun.gc.generation." + generation + ".spaces").getValue(); - } - - public String getSpaceName(long generation, long space) throws MonitorException { - return (String) vm.findByName("sun.gc.generation." + generation + ".space." + space + ".name").getValue(); - } - - public long getSpaceCapacity(long generation, long space) throws MonitorException { - return (Long) vm.findByName("sun.gc.generation." + generation + ".space." + space + ".capacity").getValue(); - } - - public long getSpaceMaxCapacity(long generation, long space) throws MonitorException { - return (Long) vm.findByName("sun.gc.generation." + generation + ".space." + space + ".maxCapacity").getValue(); - } - - public long getSpaceUsed(long generation, long space) throws MonitorException { - return (Long) vm.findByName("sun.gc.generation." + generation + ".space." + space + ".used").getValue(); - } - public long getLoadedClasses() throws MonitorException { return (Long) vm.findByName("java.cls.loadedClasses").getValue(); } diff -r 9e6bcfc40ea1 -r 0ba74f790a8a system-backend/src/main/java/com/redhat/thermostat/backend/system/JvmStatHostListener.java --- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/JvmStatHostListener.java Mon Jan 07 15:48:38 2013 -0500 +++ b/system-backend/src/main/java/com/redhat/thermostat/backend/system/JvmStatHostListener.java Mon Jan 07 15:50:03 2013 -0500 @@ -61,7 +61,6 @@ import com.redhat.thermostat.common.dao.VmClassStatDAO; import com.redhat.thermostat.common.dao.VmGcStatDAO; import com.redhat.thermostat.common.dao.VmInfoDAO; -import com.redhat.thermostat.common.dao.VmMemoryStatDAO; import com.redhat.thermostat.common.utils.LoggingUtils; import com.redhat.thermostat.storage.model.VmInfo; import com.redhat.thermostat.utils.ProcDataSource; @@ -73,7 +72,6 @@ private boolean attachNew; private final VmInfoDAO vmInfoDAO; - private final VmMemoryStatDAO vmMemoryStatDAO; private final VmClassStatDAO vmClassStatDAO; private final VmGcStatDAO vmGcStatDAO; @@ -82,10 +80,8 @@ private Set statusListeners = new CopyOnWriteArraySet(); - JvmStatHostListener(VmInfoDAO vmInfoDAO, VmMemoryStatDAO vmMemoryStatDAO, VmGcStatDAO vmGcStatDAO, - VmClassStatDAO vmClassStatDAO, boolean attachNew) { + JvmStatHostListener(VmInfoDAO vmInfoDAO, VmGcStatDAO vmGcStatDAO, VmClassStatDAO vmClassStatDAO, boolean attachNew) { this.vmInfoDAO = vmInfoDAO; - this.vmMemoryStatDAO = vmMemoryStatDAO; this.vmGcStatDAO = vmGcStatDAO; this.vmClassStatDAO = vmClassStatDAO; this.attachNew = attachNew; @@ -169,7 +165,7 @@ listeners = new CopyOnWriteArrayList<>(); } - VmListener listener = new JvmStatVmListener(vmMemoryStatDAO, vmGcStatDAO, vmId); + VmListener listener = new JvmStatVmListener(vmGcStatDAO, vmId); vm.addVmListener(listener); listeners.add(listener); diff -r 9e6bcfc40ea1 -r 0ba74f790a8a system-backend/src/main/java/com/redhat/thermostat/backend/system/JvmStatVmListener.java --- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/JvmStatVmListener.java Mon Jan 07 15:48:38 2013 -0500 +++ b/system-backend/src/main/java/com/redhat/thermostat/backend/system/JvmStatVmListener.java Mon Jan 07 15:50:03 2013 -0500 @@ -46,12 +46,8 @@ import sun.jvmstat.monitor.event.VmListener; import com.redhat.thermostat.common.dao.VmGcStatDAO; -import com.redhat.thermostat.common.dao.VmMemoryStatDAO; import com.redhat.thermostat.common.utils.LoggingUtils; import com.redhat.thermostat.storage.model.VmGcStat; -import com.redhat.thermostat.storage.model.VmMemoryStat; -import com.redhat.thermostat.storage.model.VmMemoryStat.Generation; -import com.redhat.thermostat.storage.model.VmMemoryStat.Space; public class JvmStatVmListener implements VmListener { @@ -59,11 +55,9 @@ private final int vmId; private final VmGcStatDAO gcDAO; - private final VmMemoryStatDAO memDAO; - public JvmStatVmListener(VmMemoryStatDAO vmMemoryStatDao, VmGcStatDAO vmGcStatDao, int vmId) { + public JvmStatVmListener(VmGcStatDAO vmGcStatDao, int vmId) { gcDAO = vmGcStatDao; - memDAO = vmMemoryStatDao; this.vmId = vmId; } @@ -83,7 +77,6 @@ if (vm == null) { throw new NullPointerException(); } - recordMemoryStat(vm); recordGcStat(vm); } @@ -105,38 +98,4 @@ } - private void recordMemoryStat(MonitoredVm vm) { - try { - long timestamp = System.currentTimeMillis(); - JvmStatDataExtractor extractor = new JvmStatDataExtractor(vm); - int maxGenerations = (int) extractor.getTotalGcGenerations(); - Generation[] generations = new Generation[maxGenerations]; - for (int generation = 0; generation < maxGenerations; generation++) { - Generation g = new Generation(); - g.setName(extractor.getGenerationName(generation)); - g.setCapacity(extractor.getGenerationCapacity(generation)); - g.setMaxCapacity(extractor.getGenerationMaxCapacity(generation)); - g.setCollector(extractor.getGenerationCollector(generation)); - generations[generation] = g; - int maxSpaces = (int) extractor.getTotalSpaces(generation); - Space[] spaces = new Space[maxSpaces]; - for (int space = 0; space < maxSpaces; space++) { - Space s = new Space(); - s.setIndex((int) space); - s.setName(extractor.getSpaceName(generation, space)); - s.setCapacity(extractor.getSpaceCapacity(generation, space)); - s.setMaxCapacity(extractor.getSpaceMaxCapacity(generation, space)); - s.setUsed(extractor.getSpaceUsed(generation, space)); - spaces[space] = s; - } - g.setSpaces(spaces); - } - VmMemoryStat stat = new VmMemoryStat(timestamp, vmId, generations); - memDAO.putVmMemoryStat(stat); - } catch (MonitorException e) { - logger.log(Level.WARNING, "error gathering memory info for vm " + vmId, e); - } - } - - } diff -r 9e6bcfc40ea1 -r 0ba74f790a8a system-backend/src/main/java/com/redhat/thermostat/backend/system/SystemBackend.java --- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/SystemBackend.java Mon Jan 07 15:48:38 2013 -0500 +++ b/system-backend/src/main/java/com/redhat/thermostat/backend/system/SystemBackend.java Mon Jan 07 15:50:03 2013 -0500 @@ -93,7 +93,7 @@ protected void setDAOFactoryAction() { hostInfos = df.getHostInfoDAO(); networkInterfaces = df.getNetworkInterfaceInfoDAO(); - hostListener = new JvmStatHostListener(df.getVmInfoDAO(), df.getVmMemoryStatDAO(), df.getVmGcStatDAO(), df.getVmClassStatsDAO(), getObserveNewJvm()); + hostListener = new JvmStatHostListener(df.getVmInfoDAO(), df.getVmGcStatDAO(), df.getVmClassStatsDAO(), getObserveNewJvm()); } @Override diff -r 9e6bcfc40ea1 -r 0ba74f790a8a system-backend/src/test/java/com/redhat/thermostat/backend/system/JvmStatDataExtractorTest.java --- a/system-backend/src/test/java/com/redhat/thermostat/backend/system/JvmStatDataExtractorTest.java Mon Jan 07 15:48:38 2013 -0500 +++ b/system-backend/src/test/java/com/redhat/thermostat/backend/system/JvmStatDataExtractorTest.java Mon Jan 07 15:50:03 2013 -0500 @@ -226,140 +226,6 @@ } @Test - public void testTotalGcGenerations() throws MonitorException { - final String MONITOR_NAME = "sun.gc.policy.generations"; - final Long GC_GENERATIONS = 99l; - MonitoredVm vm = buildLongMonitoredVm(MONITOR_NAME, GC_GENERATIONS); - - JvmStatDataExtractor extractor = new JvmStatDataExtractor(vm); - Long returned = extractor.getTotalGcGenerations(); - - verify(vm).findByName(eq(MONITOR_NAME)); - assertEquals(GC_GENERATIONS, returned); - } - - @Test - public void testGenerationName() throws MonitorException { - final String MONITOR_NAME = "sun.gc.generation.0.name"; - final String GENERATION_NAME = "Youth"; - MonitoredVm vm = buildStringMonitoredVm(MONITOR_NAME, GENERATION_NAME); - - JvmStatDataExtractor extractor = new JvmStatDataExtractor(vm); - String returned = extractor.getGenerationName(0); - - verify(vm).findByName(eq(MONITOR_NAME)); - assertEquals(GENERATION_NAME, returned); - } - - @Test - public void testGenerationCapacity() throws MonitorException { - final String MONITOR_NAME = "sun.gc.generation.0.capacity"; - final Long GENERATION_CAPACITY = 99l; - MonitoredVm vm = buildLongMonitoredVm(MONITOR_NAME, GENERATION_CAPACITY); - - JvmStatDataExtractor extractor = new JvmStatDataExtractor(vm); - Long returned = extractor.getGenerationCapacity(0); - - verify(vm).findByName(eq(MONITOR_NAME)); - assertEquals(GENERATION_CAPACITY, returned); - } - - @Test - public void testGenerationMaxCapacity() throws MonitorException { - final String MONITOR_NAME = "sun.gc.generation.0.maxCapacity"; - final Long GENERATION_MAX_CAPACITY = 99l; - MonitoredVm vm = buildLongMonitoredVm(MONITOR_NAME, GENERATION_MAX_CAPACITY); - - - JvmStatDataExtractor extractor = new JvmStatDataExtractor(vm); - Long returned = extractor.getGenerationMaxCapacity(0); - - verify(vm).findByName(eq(MONITOR_NAME)); - assertEquals(GENERATION_MAX_CAPACITY, returned); - } - - @Test - public void testGenerationCollector() throws MonitorException { - final String MONITOR_NAME = "sun.gc.collector.0.name"; - final String GENERATION_COLLECTOR = "generation collector"; - MonitoredVm vm = buildStringMonitoredVm(MONITOR_NAME, GENERATION_COLLECTOR); - - JvmStatDataExtractor extractor = new JvmStatDataExtractor(vm); - String returned = extractor.getGenerationCollector(0); - - verify(vm).findByName(eq(MONITOR_NAME)); - assertEquals(GENERATION_COLLECTOR, returned); - } - - @Test - public void testTotalSpaces() throws MonitorException { - final Long TOTAL_SPACES = 99l; - final LongMonitor monitor = mock(LongMonitor.class); - when(monitor.getValue()).thenReturn(TOTAL_SPACES); - MonitoredVm vm = mock(MonitoredVm.class); - when(vm.findByName("sun.gc.generation.0.spaces")).thenReturn(monitor); - - JvmStatDataExtractor extractor = new JvmStatDataExtractor(vm); - Long returned = extractor.getTotalSpaces(0); - - verify(vm).findByName(eq("sun.gc.generation.0.spaces")); - assertEquals(TOTAL_SPACES, returned); - } - - - @Test - public void testSpaceName() throws MonitorException { - final String MONITOR_NAME = "sun.gc.generation.0.space.0.name"; - final String SPACE_NAME = "Hilbert"; - MonitoredVm vm = buildStringMonitoredVm(MONITOR_NAME, SPACE_NAME); - - JvmStatDataExtractor extractor = new JvmStatDataExtractor(vm); - String returned = extractor.getSpaceName(0,0); - - verify(vm).findByName(eq(MONITOR_NAME)); - assertEquals(SPACE_NAME, returned); - } - - @Test - public void testSpaceCapacity() throws MonitorException { - final String MONITOR_NAME = "sun.gc.generation.0.space.0.capacity"; - final Long SPACE_CAPACITY = 99l; - MonitoredVm vm = buildLongMonitoredVm(MONITOR_NAME, SPACE_CAPACITY); - - JvmStatDataExtractor extractor = new JvmStatDataExtractor(vm); - Long returned = extractor.getSpaceCapacity(0,0); - - verify(vm).findByName(eq(MONITOR_NAME)); - assertEquals(SPACE_CAPACITY, returned); - } - - @Test - public void testSpaceMaxCapacity() throws MonitorException { - final String MONITOR_NAME = "sun.gc.generation.0.space.0.maxCapacity"; - final Long SPACE_MAX_CAPACITY = 99l; - MonitoredVm vm = buildLongMonitoredVm(MONITOR_NAME, SPACE_MAX_CAPACITY); - - JvmStatDataExtractor extractor = new JvmStatDataExtractor(vm); - Long returned = extractor.getSpaceMaxCapacity(0,0); - - verify(vm).findByName(eq(MONITOR_NAME)); - assertEquals(SPACE_MAX_CAPACITY, returned); - } - - @Test - public void testSpaceUsed() throws MonitorException { - final String MONITOR_NAME = "sun.gc.generation.0.space.0.used"; - final Long SPACE_USED = 99l; - MonitoredVm vm = buildLongMonitoredVm(MONITOR_NAME, SPACE_USED); - - JvmStatDataExtractor extractor = new JvmStatDataExtractor(vm); - Long returned = extractor.getSpaceUsed(0,0); - - verify(vm).findByName(eq(MONITOR_NAME)); - assertEquals(SPACE_USED, returned); - } - - @Test public void testLoadedClasses() throws MonitorException { final String MONITOR_NAME = "java.cls.loadedClasses"; final Long LOADED_CLASSES = 99l; diff -r 9e6bcfc40ea1 -r 0ba74f790a8a system-backend/src/test/java/com/redhat/thermostat/backend/system/JvmStatHostListenerTest.java --- a/system-backend/src/test/java/com/redhat/thermostat/backend/system/JvmStatHostListenerTest.java Mon Jan 07 15:48:38 2013 -0500 +++ b/system-backend/src/test/java/com/redhat/thermostat/backend/system/JvmStatHostListenerTest.java Mon Jan 07 15:50:03 2013 -0500 @@ -81,7 +81,7 @@ VmClassStatDAO vmClassDAO = mock(VmClassStatDAO.class); VmInfoDAO vmInfoDAO = mock(VmInfoDAO.class); - JvmStatHostListener l = new JvmStatHostListener(vmInfoDAO, null, null, vmClassDAO ,true); + JvmStatHostListener l = new JvmStatHostListener(vmInfoDAO, null, vmClassDAO ,true); SystemBackend backend = mock(SystemBackend.class); when(backend.getObserveNewJvm()).thenReturn(true); diff -r 9e6bcfc40ea1 -r 0ba74f790a8a vm-gc/client-core/pom.xml --- a/vm-gc/client-core/pom.xml Mon Jan 07 15:48:38 2013 -0500 +++ b/vm-gc/client-core/pom.xml Mon Jan 07 15:50:03 2013 -0500 @@ -62,6 +62,11 @@ com.redhat.thermostat + thermostat-vm-memory-common + ${project.version} + + + com.redhat.thermostat thermostat-client-core ${project.version} diff -r 9e6bcfc40ea1 -r 0ba74f790a8a vm-gc/client-core/src/main/java/com/redhat/thermostat/vm/gc/client/core/VmGcService.java --- a/vm-gc/client-core/src/main/java/com/redhat/thermostat/vm/gc/client/core/VmGcService.java Mon Jan 07 15:48:38 2013 -0500 +++ b/vm-gc/client-core/src/main/java/com/redhat/thermostat/vm/gc/client/core/VmGcService.java Mon Jan 07 15:50:03 2013 -0500 @@ -42,10 +42,10 @@ import com.redhat.thermostat.client.core.controllers.InformationServiceController; import com.redhat.thermostat.common.ApplicationService; import com.redhat.thermostat.common.dao.VmGcStatDAO; -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.vm.gc.client.core.internal.VmGcController; +import com.redhat.thermostat.vm.memory.common.VmMemoryStatDAO; public class VmGcService implements InformationService { diff -r 9e6bcfc40ea1 -r 0ba74f790a8a vm-gc/client-core/src/main/java/com/redhat/thermostat/vm/gc/client/core/internal/Activator.java --- a/vm-gc/client-core/src/main/java/com/redhat/thermostat/vm/gc/client/core/internal/Activator.java Mon Jan 07 15:48:38 2013 -0500 +++ b/vm-gc/client-core/src/main/java/com/redhat/thermostat/vm/gc/client/core/internal/Activator.java Mon Jan 07 15:50:03 2013 -0500 @@ -51,9 +51,9 @@ import com.redhat.thermostat.common.MultipleServiceTracker; import com.redhat.thermostat.common.MultipleServiceTracker.Action; import com.redhat.thermostat.common.dao.VmGcStatDAO; -import com.redhat.thermostat.common.dao.VmMemoryStatDAO; import com.redhat.thermostat.common.dao.VmRef; import com.redhat.thermostat.vm.gc.client.core.VmGcService; +import com.redhat.thermostat.vm.memory.common.VmMemoryStatDAO; public class Activator implements BundleActivator { diff -r 9e6bcfc40ea1 -r 0ba74f790a8a vm-gc/client-core/src/main/java/com/redhat/thermostat/vm/gc/client/core/internal/VmGcController.java --- a/vm-gc/client-core/src/main/java/com/redhat/thermostat/vm/gc/client/core/internal/VmGcController.java Mon Jan 07 15:48:38 2013 -0500 +++ b/vm-gc/client-core/src/main/java/com/redhat/thermostat/vm/gc/client/core/internal/VmGcController.java Mon Jan 07 15:50:03 2013 -0500 @@ -56,7 +56,6 @@ import com.redhat.thermostat.common.Timer; import com.redhat.thermostat.common.Timer.SchedulingType; import com.redhat.thermostat.common.dao.VmGcStatDAO; -import com.redhat.thermostat.common.dao.VmMemoryStatDAO; import com.redhat.thermostat.common.dao.VmRef; import com.redhat.thermostat.common.locale.Translate; import com.redhat.thermostat.storage.model.IntervalTimeData; @@ -67,6 +66,7 @@ import com.redhat.thermostat.vm.gc.client.core.VmGcView; import com.redhat.thermostat.vm.gc.client.core.VmGcViewProvider; import com.redhat.thermostat.vm.gc.client.locale.LocaleResources; +import com.redhat.thermostat.vm.memory.common.VmMemoryStatDAO; public class VmGcController implements InformationServiceController { diff -r 9e6bcfc40ea1 -r 0ba74f790a8a vm-gc/client-core/src/test/java/com/redhat/thermostat/vm/gc/client/core/internal/ActivatorTest.java --- a/vm-gc/client-core/src/test/java/com/redhat/thermostat/vm/gc/client/core/internal/ActivatorTest.java Mon Jan 07 15:48:38 2013 -0500 +++ b/vm-gc/client-core/src/test/java/com/redhat/thermostat/vm/gc/client/core/internal/ActivatorTest.java Mon Jan 07 15:50:03 2013 -0500 @@ -46,9 +46,9 @@ import com.redhat.thermostat.client.core.InformationService; import com.redhat.thermostat.common.ApplicationService; import com.redhat.thermostat.common.dao.VmGcStatDAO; -import com.redhat.thermostat.common.dao.VmMemoryStatDAO; import com.redhat.thermostat.test.StubBundleContext; import com.redhat.thermostat.vm.gc.client.core.VmGcService; +import com.redhat.thermostat.vm.memory.common.VmMemoryStatDAO; public class ActivatorTest { diff -r 9e6bcfc40ea1 -r 0ba74f790a8a vm-gc/client-core/src/test/java/com/redhat/thermostat/vm/gc/client/core/internal/VmGcControllerTest.java --- a/vm-gc/client-core/src/test/java/com/redhat/thermostat/vm/gc/client/core/internal/VmGcControllerTest.java Mon Jan 07 15:48:38 2013 -0500 +++ b/vm-gc/client-core/src/test/java/com/redhat/thermostat/vm/gc/client/core/internal/VmGcControllerTest.java Mon Jan 07 15:50:03 2013 -0500 @@ -59,14 +59,13 @@ import com.redhat.thermostat.common.Timer.SchedulingType; import com.redhat.thermostat.common.TimerFactory; import com.redhat.thermostat.common.dao.VmGcStatDAO; -import com.redhat.thermostat.common.dao.VmMemoryStatDAO; import com.redhat.thermostat.common.dao.VmRef; import com.redhat.thermostat.storage.model.VmGcStat; import com.redhat.thermostat.storage.model.VmMemoryStat; import com.redhat.thermostat.storage.model.VmMemoryStat.Generation; import com.redhat.thermostat.vm.gc.client.core.VmGcView; import com.redhat.thermostat.vm.gc.client.core.VmGcViewProvider; -import com.redhat.thermostat.vm.gc.client.core.internal.VmGcController; +import com.redhat.thermostat.vm.memory.common.VmMemoryStatDAO; public class VmGcControllerTest { diff -r 9e6bcfc40ea1 -r 0ba74f790a8a vm-heap-analysis/client-core/pom.xml --- a/vm-heap-analysis/client-core/pom.xml Mon Jan 07 15:48:38 2013 -0500 +++ b/vm-heap-analysis/client-core/pom.xml Mon Jan 07 15:50:03 2013 -0500 @@ -125,7 +125,11 @@ ${project.version} test - + + com.redhat.thermostat + thermostat-vm-memory-common + ${project.version} + com.redhat.thermostat thermostat-vm-heap-analysis-common diff -r 9e6bcfc40ea1 -r 0ba74f790a8a vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/HeapDumperService.java --- a/vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/HeapDumperService.java Mon Jan 07 15:48:38 2013 -0500 +++ b/vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/HeapDumperService.java Mon Jan 07 15:50:03 2013 -0500 @@ -41,11 +41,11 @@ import com.redhat.thermostat.client.core.controllers.InformationServiceController; import com.redhat.thermostat.client.core.NameMatchingRefFilter; import com.redhat.thermostat.common.ApplicationService; -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.vm.heap.analysis.client.core.internal.HeapDumpController; import com.redhat.thermostat.vm.heap.analysis.common.HeapDAO; +import com.redhat.thermostat.vm.memory.common.VmMemoryStatDAO; public class HeapDumperService implements InformationService { diff -r 9e6bcfc40ea1 -r 0ba74f790a8a vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/Activator.java --- a/vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/Activator.java Mon Jan 07 15:48:38 2013 -0500 +++ b/vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/Activator.java Mon Jan 07 15:50:03 2013 -0500 @@ -50,10 +50,10 @@ import com.redhat.thermostat.common.Constants; import com.redhat.thermostat.common.MultipleServiceTracker; import com.redhat.thermostat.common.MultipleServiceTracker.Action; -import com.redhat.thermostat.common.dao.VmMemoryStatDAO; import com.redhat.thermostat.common.dao.VmRef; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumperService; import com.redhat.thermostat.vm.heap.analysis.common.HeapDAO; +import com.redhat.thermostat.vm.memory.common.VmMemoryStatDAO; public class Activator implements BundleActivator { diff -r 9e6bcfc40ea1 -r 0ba74f790a8a vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/HeapDumpController.java --- a/vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/HeapDumpController.java Mon Jan 07 15:48:38 2013 -0500 +++ b/vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/HeapDumpController.java Mon Jan 07 15:50:03 2013 -0500 @@ -54,7 +54,6 @@ import com.redhat.thermostat.common.Timer; import com.redhat.thermostat.common.Timer.SchedulingType; import com.redhat.thermostat.common.cli.CommandException; -import com.redhat.thermostat.common.dao.VmMemoryStatDAO; import com.redhat.thermostat.common.dao.VmRef; import com.redhat.thermostat.common.locale.Translate; import com.redhat.thermostat.storage.model.HeapInfo; @@ -72,6 +71,7 @@ import com.redhat.thermostat.vm.heap.analysis.client.locale.LocaleResources; import com.redhat.thermostat.vm.heap.analysis.common.HeapDAO; import com.redhat.thermostat.vm.heap.analysis.common.HeapDump; +import com.redhat.thermostat.vm.memory.common.VmMemoryStatDAO; public class HeapDumpController implements InformationServiceController { diff -r 9e6bcfc40ea1 -r 0ba74f790a8a vm-heap-analysis/client-core/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/ActivatorTest.java --- a/vm-heap-analysis/client-core/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/ActivatorTest.java Mon Jan 07 15:48:38 2013 -0500 +++ b/vm-heap-analysis/client-core/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/ActivatorTest.java Mon Jan 07 15:50:03 2013 -0500 @@ -45,10 +45,10 @@ import com.redhat.thermostat.client.core.InformationService; import com.redhat.thermostat.common.ApplicationService; -import com.redhat.thermostat.common.dao.VmMemoryStatDAO; import com.redhat.thermostat.test.StubBundleContext; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumperService; import com.redhat.thermostat.vm.heap.analysis.common.HeapDAO; +import com.redhat.thermostat.vm.memory.common.VmMemoryStatDAO; public class ActivatorTest { diff -r 9e6bcfc40ea1 -r 0ba74f790a8a vm-heap-analysis/client-core/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/HeapDumpControllerTest.java --- a/vm-heap-analysis/client-core/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/HeapDumpControllerTest.java Mon Jan 07 15:48:38 2013 -0500 +++ b/vm-heap-analysis/client-core/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/HeapDumpControllerTest.java Mon Jan 07 15:50:03 2013 -0500 @@ -71,7 +71,6 @@ import com.redhat.thermostat.common.TimerFactory; import com.redhat.thermostat.common.cli.CommandException; import com.redhat.thermostat.common.dao.HostRef; -import com.redhat.thermostat.common.dao.VmMemoryStatDAO; import com.redhat.thermostat.common.dao.VmRef; import com.redhat.thermostat.storage.model.HeapInfo; import com.redhat.thermostat.storage.model.VmMemoryStat; @@ -90,6 +89,7 @@ import com.redhat.thermostat.vm.heap.analysis.client.core.ObjectRootsViewProvider; import com.redhat.thermostat.vm.heap.analysis.common.HeapDAO; import com.redhat.thermostat.vm.heap.analysis.common.HeapDump; +import com.redhat.thermostat.vm.memory.common.VmMemoryStatDAO; public class HeapDumpControllerTest { private static int TIMEOUT_MS = 1000; diff -r 9e6bcfc40ea1 -r 0ba74f790a8a vm-memory/agent/pom.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-memory/agent/pom.xml Mon Jan 07 15:50:03 2013 -0500 @@ -0,0 +1,78 @@ + + + 4.0.0 + + thermostat-vm-memory + com.redhat.thermostat + 0.5.0-SNAPSHOT + + thermostat-vm-memory-agent + bundle + Thermostat VM Memory Agent plugin + + + + org.apache.felix + maven-bundle-plugin + true + + + Red Hat, Inc. + com.redhat.thermostat.vm.memory.agent + com.redhat.thermostat.vm.memory.agent.internal.Activator + + com.redhat.thermostat.vm.memory.agent + + + com.redhat.thermostat.vm.memory.agent.internal + + + <_nouses>true + + + + + + + + junit + junit + test + + + org.mockito + mockito-core + test + + + org.osgi + org.osgi.core + provided + + + org.osgi + org.osgi.compendium + provided + + + com.redhat.thermostat + thermostat-common-core + ${project.version} + + + com.redhat.thermostat + thermostat-vm-memory-common + ${project.version} + + + com.redhat.thermostat + thermostat-agent-core + ${project.version} + + + com.redhat.thermostat + thermostat-storage-core + ${project.version} + + + diff -r 9e6bcfc40ea1 -r 0ba74f790a8a vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/internal/Activator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/internal/Activator.java Mon Jan 07 15:50:03 2013 -0500 @@ -0,0 +1,96 @@ +/* + * Copyright 2013 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 + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.memory.agent.internal; + +import java.util.Map; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceRegistration; + +import com.redhat.thermostat.backend.Backend; +import com.redhat.thermostat.backend.BackendService; +import com.redhat.thermostat.common.MultipleServiceTracker; +import com.redhat.thermostat.common.MultipleServiceTracker.Action; +import com.redhat.thermostat.common.Version; +import com.redhat.thermostat.vm.memory.common.VmMemoryStatDAO; + +public class Activator implements BundleActivator { + + private MultipleServiceTracker tracker; + private VmMemoryBackend backend; + private ServiceRegistration reg; + + @Override + public void start(final BundleContext context) throws Exception { + Class[] deps = new Class[] { + BackendService.class, + VmMemoryStatDAO.class + }; + tracker = new MultipleServiceTracker(context, deps, new Action() { + + @Override + public void dependenciesAvailable(Map services) { + VmMemoryStatDAO vmMemoryStatDao = (VmMemoryStatDAO) services.get(VmMemoryStatDAO.class.getName()); + Version version = new Version(context.getBundle()); + backend = new VmMemoryBackend(vmMemoryStatDao, version); + reg = context.registerService(Backend.class.getName(), backend, null); + } + + @Override + public void dependenciesUnavailable() { + if (backend.isActive()) { + backend.deactivate(); + } + reg.unregister(); + } + }); + tracker.open(); + } + + @Override + public void stop(BundleContext context) throws Exception { + tracker.close(); + } + + /* + * For testing purposes only. + */ + VmMemoryBackend getBackend() { + return backend; + } +} diff -r 9e6bcfc40ea1 -r 0ba74f790a8a vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/internal/VmMemoryBackend.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/internal/VmMemoryBackend.java Mon Jan 07 15:50:03 2013 -0500 @@ -0,0 +1,141 @@ +/* + * Copyright 2013 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 + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.memory.agent.internal; + +import java.net.URISyntaxException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import sun.jvmstat.monitor.HostIdentifier; +import sun.jvmstat.monitor.MonitorException; +import sun.jvmstat.monitor.MonitoredHost; + +import com.redhat.thermostat.backend.Backend; +import com.redhat.thermostat.backend.BackendID; +import com.redhat.thermostat.backend.BackendsProperties; +import com.redhat.thermostat.common.Version; +import com.redhat.thermostat.common.utils.LoggingUtils; +import com.redhat.thermostat.vm.memory.common.VmMemoryStatDAO; + +public class VmMemoryBackend extends Backend { + + private static final Logger LOGGER = LoggingUtils.getLogger(VmMemoryBackend.class); + + private VmMemoryStatDAO vmMemoryStats; + private HostIdentifier hostId; + private MonitoredHost host; + private VmMemoryHostListener hostListener; + private boolean started; + + public VmMemoryBackend(VmMemoryStatDAO vmMemoryStatDAO, Version version) { + super(new BackendID("VM Memory Backend", VmMemoryBackend.class.getName())); + this.vmMemoryStats = vmMemoryStatDAO; + + setConfigurationValue(BackendsProperties.VENDOR.name(), "Red Hat, Inc."); + setConfigurationValue(BackendsProperties.DESCRIPTION.name(), "Gathers memory statistics about a JVM"); + setConfigurationValue(BackendsProperties.VERSION.name(), version.getVersionNumber()); + + try { + hostId = new HostIdentifier((String) null); + host = MonitoredHost.getMonitoredHost(hostId); + hostListener = new VmMemoryHostListener(vmMemoryStats, attachToNewProcessByDefault()); + } catch (MonitorException me) { + LOGGER.log(Level.WARNING, "Problems with connecting jvmstat to local machine", me); + } catch (URISyntaxException use) { + LOGGER.log(Level.WARNING, "Failed to create host identifier", use); + } + } + + @Override + public boolean activate() { + if (!started && host != null) { + try { + host.addHostListener(hostListener); + started = true; + } catch (MonitorException me) { + LOGGER.log(Level.WARNING, "Failed to add host listener", me); + } + } + return started; + } + + @Override + public boolean deactivate() { + if (started && host != null) { + try { + host.removeHostListener(hostListener); + started = false; + } catch (MonitorException me) { + LOGGER.log(Level.INFO, "Failed to remove host listener"); + } + } + return !started; + } + + @Override + public boolean isActive() { + return started; + } + + @Override + protected void setDAOFactoryAction() { + // No need for DAOFactory + } + + @Override + public String getConfigurationValue(String key) { + return null; + } + + @Override + public boolean attachToNewProcessByDefault() { + return true; + } + + @Override + public int getOrderValue() { + return ORDER_MEMORY_GROUP + 40; + } + + /* + * For testing purposes only. + */ + void setHost(MonitoredHost host) { + this.host = host; + } + +} diff -r 9e6bcfc40ea1 -r 0ba74f790a8a vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/internal/VmMemoryDataExtractor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/internal/VmMemoryDataExtractor.java Mon Jan 07 15:50:03 2013 -0500 @@ -0,0 +1,117 @@ +/* + * Copyright 2013 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 + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.memory.agent.internal; + +import sun.jvmstat.monitor.Monitor; +import sun.jvmstat.monitor.MonitorException; +import sun.jvmstat.monitor.MonitoredVm; + +import com.redhat.thermostat.storage.model.VmMemoryStat.Generation; + +/** + * A helper class to provide type-safe access to commonly used jvmstat monitors + *

+ * Implementation details: For local vms, jvmstat uses a ByteBuffer + * corresponding to mmap()ed hsperfdata file. The hsperfdata file is updated + * asynchronously by the vm that created the file. The polling that jvmstat api + * provides is merely an abstraction over this (possibly always up-to-date) + * ByteBuffer. So the data this class extracts is as current as possible, and + * does not correspond to when the jvmstat update events fired. + */ +public class VmMemoryDataExtractor { + + /* + * Note, there may be a performance issue to consider here. We have a lot of + * string constants. When we start adding some of the more heavyweight + * features, and running into CPU issues this may need to be reconsidered in + * order to avoid the String pool overhead. See also: + * http://docs.oracle.com/javase/6/docs/api/java/lang/String.html#intern() + */ + + private final MonitoredVm vm; + + public VmMemoryDataExtractor(MonitoredVm vm) { + this.vm = vm; + } + + public long getTotalGcGenerations() throws MonitorException { + return (Long) vm.findByName("sun.gc.policy.generations").getValue(); + } + + public String getGenerationName(long generation) throws MonitorException { + return (String) vm.findByName("sun.gc.generation." + generation + ".name").getValue(); + } + + public long getGenerationCapacity(long generation) throws MonitorException { + return (Long) vm.findByName("sun.gc.generation." + generation + ".capacity").getValue(); + } + + public long getGenerationMaxCapacity(long generation) throws MonitorException { + return (Long) vm.findByName("sun.gc.generation." + generation + ".maxCapacity").getValue(); + } + + public String getGenerationCollector(long generation) throws MonitorException { + // this is just re-implementing getCollectorName() + // TODO check generation number and collector number are always associated + Monitor m = vm.findByName("sun.gc.collector." + generation + ".name"); + if (m == null) { + return Generation.COLLECTOR_NONE; + } + return (String) m.getValue(); + } + + public long getTotalSpaces(long generation) throws MonitorException { + return (Long) vm.findByName("sun.gc.generation." + generation + ".spaces").getValue(); + } + + public String getSpaceName(long generation, long space) throws MonitorException { + return (String) vm.findByName("sun.gc.generation." + generation + ".space." + space + ".name").getValue(); + } + + public long getSpaceCapacity(long generation, long space) throws MonitorException { + return (Long) vm.findByName("sun.gc.generation." + generation + ".space." + space + ".capacity").getValue(); + } + + public long getSpaceMaxCapacity(long generation, long space) throws MonitorException { + return (Long) vm.findByName("sun.gc.generation." + generation + ".space." + space + ".maxCapacity").getValue(); + } + + public long getSpaceUsed(long generation, long space) throws MonitorException { + return (Long) vm.findByName("sun.gc.generation." + generation + ".space." + space + ".used").getValue(); + } + +} diff -r 9e6bcfc40ea1 -r 0ba74f790a8a vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/internal/VmMemoryHostListener.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/internal/VmMemoryHostListener.java Mon Jan 07 15:50:03 2013 -0500 @@ -0,0 +1,172 @@ +/* + * Copyright 2013 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 + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.memory.agent.internal; + +import java.net.URISyntaxException; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Level; +import java.util.logging.Logger; + +import sun.jvmstat.monitor.MonitorException; +import sun.jvmstat.monitor.MonitoredHost; +import sun.jvmstat.monitor.MonitoredVm; +import sun.jvmstat.monitor.VmIdentifier; +import sun.jvmstat.monitor.event.HostEvent; +import sun.jvmstat.monitor.event.HostListener; +import sun.jvmstat.monitor.event.VmListener; +import sun.jvmstat.monitor.event.VmStatusChangeEvent; + +import com.redhat.thermostat.common.utils.LoggingUtils; +import com.redhat.thermostat.vm.memory.common.VmMemoryStatDAO; + +public class VmMemoryHostListener implements HostListener { + + private static final Logger logger = LoggingUtils.getLogger(VmMemoryHostListener.class); + + private boolean attachNew; + + private final VmMemoryStatDAO vmMemoryStatDAO; + + private Map monitoredVms = new HashMap<>(); + private Map registeredListeners = new ConcurrentHashMap<>(); + + VmMemoryHostListener(VmMemoryStatDAO vmMemoryStatDAO, boolean attachNew) { + this.vmMemoryStatDAO = vmMemoryStatDAO; + this.attachNew = attachNew; + } + + void removeAllListeners() { + for (MonitoredVm vm : monitoredVms.values()) { + VmListener listener = registeredListeners.get(vm); + try { + if (listener != null) { + vm.removeVmListener(listener); + } + } catch (MonitorException e) { + logger.log(Level.WARNING, "can't remove vm listener", e); + } + } + } + + @Override + public void disconnected(HostEvent event) { + logger.warning("Disconnected from host"); + } + + @SuppressWarnings("unchecked") // Unchecked casts to (Set). + @Override + public void vmStatusChanged(VmStatusChangeEvent event) { + MonitoredHost host = event.getMonitoredHost(); + + for (Integer newVm : (Set) event.getStarted()) { + try { + logger.fine("New vm: " + newVm); + sendNewVM(newVm, host); + } catch (MonitorException e) { + logger.log(Level.WARNING, "error getting info for new vm" + newVm, e); + } catch (URISyntaxException e) { + logger.log(Level.WARNING, "error getting info for new vm" + newVm, e); + } + } + + for (Integer stoppedVm : (Set) event.getTerminated()) { + try { + logger.fine("stopped vm: " + stoppedVm); + sendStoppedVM(stoppedVm, host); + } catch (URISyntaxException e) { + logger.log(Level.WARNING, "error getting info for stopped vm" + stoppedVm, e); + } catch (MonitorException e) { + logger.log(Level.WARNING, "error getting info for stopped vm" + stoppedVm, e); + } + } + } + + private void sendNewVM(Integer vmId, MonitoredHost host) + throws MonitorException, URISyntaxException { + MonitoredVm vm = host.getMonitoredVm(host.getHostIdentifier().resolve( + new VmIdentifier(vmId.toString()))); + if (vm != null) { + + if (attachNew) { + VmMemoryVmListener listener = new VmMemoryVmListener(vmMemoryStatDAO, vmId); + vm.addVmListener(listener); + registeredListeners.put(vm, listener); + logger.finer("Attached VmListener for VM: " + vmId); + + } else { + logger.log(Level.FINE, "skipping new vm " + vmId); + } + + monitoredVms.put(vmId, vm); + } + } + + private void sendStoppedVM(Integer vmId, MonitoredHost host) throws URISyntaxException, MonitorException { + + VmIdentifier resolvedVmID = host.getHostIdentifier().resolve(new VmIdentifier(vmId.toString())); + if (resolvedVmID != null) { + MonitoredVm vm = monitoredVms.remove(vmId); + VmMemoryVmListener listener = registeredListeners.remove(vm); + try { + if (listener != null) { + vm.removeVmListener(listener); + } + } catch (MonitorException e) { + logger.log(Level.WARNING, "can't remove vm listener", e); + } + vm.detach(); + } + } + + /* + * For testing purposes only. + */ + Map getMonitoredVms() { + return monitoredVms; + } + + /* + * For testing purposes only. + */ + Map getRegisteredListeners() { + return registeredListeners; + } + +} diff -r 9e6bcfc40ea1 -r 0ba74f790a8a vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/internal/VmMemoryVmListener.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/internal/VmMemoryVmListener.java Mon Jan 07 15:50:03 2013 -0500 @@ -0,0 +1,120 @@ +/* + * Copyright 2013 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 + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.memory.agent.internal; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import sun.jvmstat.monitor.MonitorException; +import sun.jvmstat.monitor.MonitoredVm; +import sun.jvmstat.monitor.event.MonitorStatusChangeEvent; +import sun.jvmstat.monitor.event.VmEvent; +import sun.jvmstat.monitor.event.VmListener; + +import com.redhat.thermostat.common.utils.LoggingUtils; +import com.redhat.thermostat.storage.model.VmMemoryStat; +import com.redhat.thermostat.storage.model.VmMemoryStat.Generation; +import com.redhat.thermostat.storage.model.VmMemoryStat.Space; +import com.redhat.thermostat.vm.memory.common.VmMemoryStatDAO; + +public class VmMemoryVmListener implements VmListener { + + private static final Logger logger = LoggingUtils.getLogger(VmMemoryVmListener.class); + + private final int vmId; + private final VmMemoryStatDAO memDAO; + + public VmMemoryVmListener(VmMemoryStatDAO vmMemoryStatDao, int vmId) { + memDAO = vmMemoryStatDao; + this.vmId = vmId; + } + + @Override + public void disconnected(VmEvent event) { + /* nothing to do here */ + } + + @Override + public void monitorStatusChanged(MonitorStatusChangeEvent event) { + /* nothing to do here */ + } + + @Override + public void monitorsUpdated(VmEvent event) { + MonitoredVm vm = event.getMonitoredVm(); + if (vm == null) { + throw new NullPointerException(); + } + + VmMemoryDataExtractor extractor = new VmMemoryDataExtractor(vm); + recordMemoryStat(vm, extractor); + } + + void recordMemoryStat(MonitoredVm vm, VmMemoryDataExtractor extractor) { + try { + long timestamp = System.currentTimeMillis(); + int maxGenerations = (int) extractor.getTotalGcGenerations(); + Generation[] generations = new Generation[maxGenerations]; + for (int generation = 0; generation < maxGenerations; generation++) { + Generation g = new Generation(); + g.setName(extractor.getGenerationName(generation)); + g.setCapacity(extractor.getGenerationCapacity(generation)); + g.setMaxCapacity(extractor.getGenerationMaxCapacity(generation)); + g.setCollector(extractor.getGenerationCollector(generation)); + generations[generation] = g; + int maxSpaces = (int) extractor.getTotalSpaces(generation); + Space[] spaces = new Space[maxSpaces]; + for (int space = 0; space < maxSpaces; space++) { + Space s = new Space(); + s.setIndex((int) space); + s.setName(extractor.getSpaceName(generation, space)); + s.setCapacity(extractor.getSpaceCapacity(generation, space)); + s.setMaxCapacity(extractor.getSpaceMaxCapacity(generation, space)); + s.setUsed(extractor.getSpaceUsed(generation, space)); + spaces[space] = s; + } + g.setSpaces(spaces); + } + VmMemoryStat stat = new VmMemoryStat(timestamp, vmId, generations); + memDAO.putVmMemoryStat(stat); + } catch (MonitorException e) { + logger.log(Level.WARNING, "error gathering memory info for vm " + vmId, e); + } + } + + +} diff -r 9e6bcfc40ea1 -r 0ba74f790a8a vm-memory/agent/src/test/java/com/redhat/thermostat/vm/memory/agent/internal/ActivatorTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-memory/agent/src/test/java/com/redhat/thermostat/vm/memory/agent/internal/ActivatorTest.java Mon Jan 07 15:50:03 2013 -0500 @@ -0,0 +1,104 @@ +/* + * Copyright 2013 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 + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.memory.agent.internal; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.junit.Test; +import org.osgi.framework.Bundle; +import org.osgi.framework.Version; + +import com.redhat.thermostat.backend.Backend; +import com.redhat.thermostat.backend.BackendService; +import com.redhat.thermostat.test.StubBundleContext; +import com.redhat.thermostat.vm.memory.common.VmMemoryStatDAO; + +public class ActivatorTest { + + @Test + public void verifyActivatorDoesNotRegisterServiceOnMissingDeps() throws Exception { + StubBundleContext context = new StubBundleContext(); + + Activator activator = new Activator(); + + activator.start(context); + + assertEquals(0, context.getAllServices().size()); + assertEquals(2, context.getServiceListeners().size()); + + activator.stop(context); + } + + @Test + public void verifyActivatorRegistersServices() throws Exception { + StubBundleContext context = new StubBundleContext() { + @Override + public Bundle getBundle() { + Bundle result = mock(Bundle.class); + when(result.getVersion()).thenReturn(Version.emptyVersion); + return result; + } + }; + + BackendService service = mock(BackendService.class); + VmMemoryStatDAO vmMemoryStatDAO = mock(VmMemoryStatDAO.class); + + context.registerService(BackendService.class, service, null); + context.registerService(VmMemoryStatDAO.class, vmMemoryStatDAO, null); + + Activator activator = new Activator(); + + activator.start(context); + + assertTrue(context.isServiceRegistered(Backend.class.getName(), VmMemoryBackend.class)); + VmMemoryBackend backend = activator.getBackend(); + assertNotNull(backend); + + activator.stop(context); + + assertFalse(backend.isActive()); + + assertEquals(0, context.getServiceListeners().size()); + assertEquals(2, context.getAllServices().size()); + } + +} diff -r 9e6bcfc40ea1 -r 0ba74f790a8a vm-memory/agent/src/test/java/com/redhat/thermostat/vm/memory/agent/internal/VmMemoryBackendTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-memory/agent/src/test/java/com/redhat/thermostat/vm/memory/agent/internal/VmMemoryBackendTest.java Mon Jan 07 15:50:03 2013 -0500 @@ -0,0 +1,90 @@ +/* + * Copyright 2013 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 + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.memory.agent.internal; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.net.URISyntaxException; + +import org.junit.Before; +import org.junit.Test; + +import sun.jvmstat.monitor.MonitorException; +import sun.jvmstat.monitor.MonitoredHost; +import sun.jvmstat.monitor.event.HostListener; + +import com.redhat.thermostat.common.Version; +import com.redhat.thermostat.vm.memory.common.VmMemoryStatDAO; + +public class VmMemoryBackendTest { + + private VmMemoryBackend backend; + private MonitoredHost host; + + @Before + public void setup() throws MonitorException, URISyntaxException { + VmMemoryStatDAO vmMemoryStatDao = mock(VmMemoryStatDAO.class); + + Version version = mock(Version.class); + when(version.getVersionNumber()).thenReturn("0.0.0"); + backend = new VmMemoryBackend(vmMemoryStatDao, version); + + host = mock(MonitoredHost.class); + backend.setHost(host); + } + + @Test + public void testStart() throws MonitorException { + backend.activate(); + verify(host).addHostListener(any(HostListener.class)); + assertTrue(backend.isActive()); + } + + @Test + public void testStop() throws MonitorException { + backend.activate(); + backend.deactivate(); + verify(host).removeHostListener(any(HostListener.class)); + assertFalse(backend.isActive()); + } + +} diff -r 9e6bcfc40ea1 -r 0ba74f790a8a vm-memory/agent/src/test/java/com/redhat/thermostat/vm/memory/agent/internal/VmMemoryDataExtractorTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-memory/agent/src/test/java/com/redhat/thermostat/vm/memory/agent/internal/VmMemoryDataExtractorTest.java Mon Jan 07 15:50:03 2013 -0500 @@ -0,0 +1,206 @@ +/* + * Copyright 2013 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 + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.memory.agent.internal; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import org.junit.Test; + +import sun.jvmstat.monitor.LongMonitor; +import sun.jvmstat.monitor.MonitorException; +import sun.jvmstat.monitor.MonitoredVm; +import sun.jvmstat.monitor.StringMonitor; + +public class VmMemoryDataExtractorTest { + + private MonitoredVm buildStringMonitoredVm(String monitorName, String monitorReturn) throws MonitorException { + final StringMonitor monitor = mock(StringMonitor.class); + when(monitor.stringValue()).thenReturn(monitorReturn); + when(monitor.getValue()).thenReturn(monitorReturn); + MonitoredVm vm = mock(MonitoredVm.class); + when(vm.findByName(monitorName)).thenReturn(monitor); + return vm; + } + + private MonitoredVm buildLongMonitoredVm(String monitorName, Long monitorReturn) throws MonitorException { + final LongMonitor monitor = mock(LongMonitor.class); + when(monitor.longValue()).thenReturn(monitorReturn); + when(monitor.getValue()).thenReturn(monitorReturn); + MonitoredVm vm = mock(MonitoredVm.class); + when(vm.findByName(monitorName)).thenReturn(monitor); + return vm; + } + + @Test + public void testTotalGcGenerations() throws MonitorException { + final String MONITOR_NAME = "sun.gc.policy.generations"; + final Long GC_GENERATIONS = 99l; + MonitoredVm vm = buildLongMonitoredVm(MONITOR_NAME, GC_GENERATIONS); + + VmMemoryDataExtractor extractor = new VmMemoryDataExtractor(vm); + Long returned = extractor.getTotalGcGenerations(); + + verify(vm).findByName(eq(MONITOR_NAME)); + assertEquals(GC_GENERATIONS, returned); + } + + @Test + public void testGenerationName() throws MonitorException { + final String MONITOR_NAME = "sun.gc.generation.0.name"; + final String GENERATION_NAME = "Youth"; + MonitoredVm vm = buildStringMonitoredVm(MONITOR_NAME, GENERATION_NAME); + + VmMemoryDataExtractor extractor = new VmMemoryDataExtractor(vm); + String returned = extractor.getGenerationName(0); + + verify(vm).findByName(eq(MONITOR_NAME)); + assertEquals(GENERATION_NAME, returned); + } + + @Test + public void testGenerationCapacity() throws MonitorException { + final String MONITOR_NAME = "sun.gc.generation.0.capacity"; + final Long GENERATION_CAPACITY = 99l; + MonitoredVm vm = buildLongMonitoredVm(MONITOR_NAME, GENERATION_CAPACITY); + + VmMemoryDataExtractor extractor = new VmMemoryDataExtractor(vm); + Long returned = extractor.getGenerationCapacity(0); + + verify(vm).findByName(eq(MONITOR_NAME)); + assertEquals(GENERATION_CAPACITY, returned); + } + + @Test + public void testGenerationMaxCapacity() throws MonitorException { + final String MONITOR_NAME = "sun.gc.generation.0.maxCapacity"; + final Long GENERATION_MAX_CAPACITY = 99l; + MonitoredVm vm = buildLongMonitoredVm(MONITOR_NAME, GENERATION_MAX_CAPACITY); + + + VmMemoryDataExtractor extractor = new VmMemoryDataExtractor(vm); + Long returned = extractor.getGenerationMaxCapacity(0); + + verify(vm).findByName(eq(MONITOR_NAME)); + assertEquals(GENERATION_MAX_CAPACITY, returned); + } + + @Test + public void testGenerationCollector() throws MonitorException { + final String MONITOR_NAME = "sun.gc.collector.0.name"; + final String GENERATION_COLLECTOR = "generation collector"; + MonitoredVm vm = buildStringMonitoredVm(MONITOR_NAME, GENERATION_COLLECTOR); + + VmMemoryDataExtractor extractor = new VmMemoryDataExtractor(vm); + String returned = extractor.getGenerationCollector(0); + + verify(vm).findByName(eq(MONITOR_NAME)); + assertEquals(GENERATION_COLLECTOR, returned); + } + + @Test + public void testTotalSpaces() throws MonitorException { + final Long TOTAL_SPACES = 99l; + final LongMonitor monitor = mock(LongMonitor.class); + when(monitor.getValue()).thenReturn(TOTAL_SPACES); + MonitoredVm vm = mock(MonitoredVm.class); + when(vm.findByName("sun.gc.generation.0.spaces")).thenReturn(monitor); + + VmMemoryDataExtractor extractor = new VmMemoryDataExtractor(vm); + Long returned = extractor.getTotalSpaces(0); + + verify(vm).findByName(eq("sun.gc.generation.0.spaces")); + assertEquals(TOTAL_SPACES, returned); + } + + + @Test + public void testSpaceName() throws MonitorException { + final String MONITOR_NAME = "sun.gc.generation.0.space.0.name"; + final String SPACE_NAME = "Hilbert"; + MonitoredVm vm = buildStringMonitoredVm(MONITOR_NAME, SPACE_NAME); + + VmMemoryDataExtractor extractor = new VmMemoryDataExtractor(vm); + String returned = extractor.getSpaceName(0,0); + + verify(vm).findByName(eq(MONITOR_NAME)); + assertEquals(SPACE_NAME, returned); + } + + @Test + public void testSpaceCapacity() throws MonitorException { + final String MONITOR_NAME = "sun.gc.generation.0.space.0.capacity"; + final Long SPACE_CAPACITY = 99l; + MonitoredVm vm = buildLongMonitoredVm(MONITOR_NAME, SPACE_CAPACITY); + + VmMemoryDataExtractor extractor = new VmMemoryDataExtractor(vm); + Long returned = extractor.getSpaceCapacity(0,0); + + verify(vm).findByName(eq(MONITOR_NAME)); + assertEquals(SPACE_CAPACITY, returned); + } + + @Test + public void testSpaceMaxCapacity() throws MonitorException { + final String MONITOR_NAME = "sun.gc.generation.0.space.0.maxCapacity"; + final Long SPACE_MAX_CAPACITY = 99l; + MonitoredVm vm = buildLongMonitoredVm(MONITOR_NAME, SPACE_MAX_CAPACITY); + + VmMemoryDataExtractor extractor = new VmMemoryDataExtractor(vm); + Long returned = extractor.getSpaceMaxCapacity(0,0); + + verify(vm).findByName(eq(MONITOR_NAME)); + assertEquals(SPACE_MAX_CAPACITY, returned); + } + + @Test + public void testSpaceUsed() throws MonitorException { + final String MONITOR_NAME = "sun.gc.generation.0.space.0.used"; + final Long SPACE_USED = 99l; + MonitoredVm vm = buildLongMonitoredVm(MONITOR_NAME, SPACE_USED); + + VmMemoryDataExtractor extractor = new VmMemoryDataExtractor(vm); + Long returned = extractor.getSpaceUsed(0,0); + + verify(vm).findByName(eq(MONITOR_NAME)); + assertEquals(SPACE_USED, returned); + } + +} diff -r 9e6bcfc40ea1 -r 0ba74f790a8a vm-memory/agent/src/test/java/com/redhat/thermostat/vm/memory/agent/internal/VmMemoryHostListenerTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-memory/agent/src/test/java/com/redhat/thermostat/vm/memory/agent/internal/VmMemoryHostListenerTest.java Mon Jan 07 15:50:03 2013 -0500 @@ -0,0 +1,136 @@ +/* + * Copyright 2013 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 + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.memory.agent.internal; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.net.URISyntaxException; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import org.junit.Before; +import org.junit.Test; + +import sun.jvmstat.monitor.HostIdentifier; +import sun.jvmstat.monitor.MonitorException; +import sun.jvmstat.monitor.MonitoredHost; +import sun.jvmstat.monitor.MonitoredVm; +import sun.jvmstat.monitor.VmIdentifier; +import sun.jvmstat.monitor.event.VmStatusChangeEvent; + +import com.redhat.thermostat.vm.memory.common.VmMemoryStatDAO; + +public class VmMemoryHostListenerTest { + + private VmMemoryHostListener hostListener; + private MonitoredHost host; + private MonitoredVm monitoredVm1; + private MonitoredVm monitoredVm2; + + @Before + public void setup() throws MonitorException, URISyntaxException { + VmMemoryStatDAO vmMemoryStatDAO = mock(VmMemoryStatDAO.class); + hostListener = new VmMemoryHostListener(vmMemoryStatDAO, true); + + host = mock(MonitoredHost.class); + HostIdentifier hostId = mock(HostIdentifier.class); + monitoredVm1 = mock(MonitoredVm.class); + monitoredVm2 = mock(MonitoredVm.class); + VmIdentifier vmId1 = new VmIdentifier("1"); + VmIdentifier vmId2 = new VmIdentifier("2"); + when(host.getHostIdentifier()).thenReturn(hostId); + when(host.getMonitoredVm(eq(vmId1))).thenReturn(monitoredVm1); + when(host.getMonitoredVm(eq(vmId2))).thenReturn(monitoredVm2); + when(hostId.resolve(eq(vmId1))).thenReturn(vmId1); + when(hostId.resolve(eq(vmId2))).thenReturn(vmId2); + } + + @Test + public void testNewVM() throws InterruptedException, MonitorException { + startVMs(); + + assertTrue(hostListener.getMonitoredVms().containsKey(1)); + assertTrue(hostListener.getMonitoredVms().containsKey(2)); + assertEquals(monitoredVm1, hostListener.getMonitoredVms().get(1)); + assertEquals(monitoredVm2, hostListener.getMonitoredVms().get(2)); + + assertTrue(hostListener.getRegisteredListeners().containsKey(monitoredVm1)); + assertTrue(hostListener.getRegisteredListeners().containsKey(monitoredVm2)); + } + + @Test + public void testStoppedVM() throws InterruptedException, MonitorException { + final Set stopped = new HashSet<>(); + stopped.add(1); + + startVMs(); + + // Trigger a change event + VmStatusChangeEvent event = mock(VmStatusChangeEvent.class); + when(event.getMonitoredHost()).thenReturn(host); + when(event.getStarted()).thenReturn(Collections.emptySet()); + when(event.getTerminated()).thenReturn(stopped); + hostListener.vmStatusChanged(event); + + // Ensure only 1 removed + assertFalse(hostListener.getMonitoredVms().containsKey(1)); + assertTrue(hostListener.getMonitoredVms().containsKey(2)); + assertEquals(monitoredVm2, hostListener.getMonitoredVms().get(2)); + + assertFalse(hostListener.getRegisteredListeners().containsKey(monitoredVm1)); + assertTrue(hostListener.getRegisteredListeners().containsKey(monitoredVm2)); + } + + private void startVMs() throws InterruptedException, MonitorException { + final Set started = new HashSet<>(); + started.add(1); + started.add(2); + + // Trigger a change event + VmStatusChangeEvent event = mock(VmStatusChangeEvent.class); + when(event.getMonitoredHost()).thenReturn(host); + when(event.getStarted()).thenReturn(started); + when(event.getTerminated()).thenReturn(Collections.emptySet()); + hostListener.vmStatusChanged(event); + } +} diff -r 9e6bcfc40ea1 -r 0ba74f790a8a vm-memory/agent/src/test/java/com/redhat/thermostat/vm/memory/agent/internal/VmMemoryVmListenerTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-memory/agent/src/test/java/com/redhat/thermostat/vm/memory/agent/internal/VmMemoryVmListenerTest.java Mon Jan 07 15:50:03 2013 -0500 @@ -0,0 +1,170 @@ +/* + * Copyright 2013 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 + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.memory.agent.internal; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; + +import sun.jvmstat.monitor.MonitorException; +import sun.jvmstat.monitor.MonitoredVm; + +import com.redhat.thermostat.storage.model.VmMemoryStat; +import com.redhat.thermostat.storage.model.VmMemoryStat.Generation; +import com.redhat.thermostat.storage.model.VmMemoryStat.Space; +import com.redhat.thermostat.vm.memory.common.VmMemoryStatDAO; + +public class VmMemoryVmListenerTest { + private static final String[] GEN_NAMES = new String[] { "Gen1", "Gen2" }; + private static final Long[] GEN_CAPS = new Long[] { 500L, 1000L }; + private static final Long[] GEN_MAX_CAPS = new Long[] { 5000L, 10000L }; + private static final String[] GEN_GCS = new String[] { "GC1", "GC2" }; + private static final Long[] GEN_SPACES = new Long[] { 2L, 1L }; + private static final String[][] SPACE_NAME = new String[][] { + { "Space1", "Space2" }, + { "Space3" } + }; + private static final Long[][] SPACE_CAPS = new Long[][] { + { 225L, 275L }, + { 1000L } + }; + private static final Long[][] SPACE_MAX_CAPS = new Long[][] { + { 2250L, 2750L }, + { 10000L } + }; + private static final Long[][] SPACE_USED = new Long[][] { + { 125L, 175L }, + { 900L } + }; + + private VmMemoryVmListener vmListener; + private MonitoredVm monitoredVm; + private VmMemoryDataExtractor extractor; + private VmMemoryStatDAO vmMemoryStatDAO; + + @Before + public void setup() throws MonitorException { + final int numGens = 2; + vmMemoryStatDAO = mock(VmMemoryStatDAO.class); + vmListener = new VmMemoryVmListener(vmMemoryStatDAO, 0); + + monitoredVm = mock(MonitoredVm.class); + extractor = mock(VmMemoryDataExtractor.class); + + for (int i = 0; i < numGens; i++) { + mockGenerationName(i); + mockGenerationCapacity(i); + mockGenerationMaxCapacity(i); + mockGenerationGC(i); + mockTotalSpaces(i); + int numSpaces = GEN_SPACES[i].intValue(); + for (int j = 0; j < numSpaces; j++) { + mockSpaceName(i, j); + mockSpaceCapacity(i, j); + mockSpaceMaxCapacity(i, j); + mockSpaceUsed(i, j); + } + } + } + + private void mockGenerationName(int gen) throws MonitorException { + when(extractor.getGenerationName(gen)).thenReturn(GEN_NAMES[gen]); + } + + private void mockGenerationCapacity(int gen) throws MonitorException { + when(extractor.getGenerationCapacity(gen)).thenReturn(GEN_CAPS[gen]); + } + + private void mockGenerationMaxCapacity(int gen) throws MonitorException { + when(extractor.getGenerationMaxCapacity(gen)).thenReturn(GEN_MAX_CAPS[gen]); + } + + private void mockGenerationGC(int gen) throws MonitorException { + when(extractor.getGenerationCollector(gen)).thenReturn(GEN_GCS[gen]); + } + + private void mockTotalSpaces(int gen) throws MonitorException { + when(extractor.getTotalSpaces(gen)).thenReturn(GEN_SPACES[gen]); + } + + private void mockSpaceName(int gen, int space) throws MonitorException { + when(extractor.getSpaceName(gen, space)).thenReturn(SPACE_NAME[gen][space]); + } + + private void mockSpaceCapacity(int gen, int space) throws MonitorException { + when(extractor.getSpaceCapacity(gen, space)).thenReturn(SPACE_CAPS[gen][space]); + } + + private void mockSpaceMaxCapacity(int gen, int space) throws MonitorException { + when(extractor.getSpaceMaxCapacity(gen, space)).thenReturn(SPACE_MAX_CAPS[gen][space]); + } + + private void mockSpaceUsed(int gen, int space) throws MonitorException { + when(extractor.getSpaceUsed(gen, space)).thenReturn(SPACE_USED[gen][space]); + } + + @Test + public void testRecordMemoryStat() { + vmListener.recordMemoryStat(monitoredVm, extractor); + ArgumentCaptor captor = ArgumentCaptor.forClass(VmMemoryStat.class); + verify(vmMemoryStatDAO).putVmMemoryStat(captor.capture()); + VmMemoryStat memoryStat = captor.getValue(); + + Generation[] gens = memoryStat.getGenerations(); + for (int i = 0; i < gens.length; i++) { + Generation gen = gens[i]; + assertEquals(GEN_NAMES[i], gen.getName()); + assertEquals(GEN_CAPS[i], (Long) gen.getCapacity()); + assertEquals(GEN_MAX_CAPS[i], (Long) gen.getMaxCapacity()); + assertEquals(GEN_GCS[i], gen.getCollector()); + assertEquals(GEN_SPACES[i], Long.valueOf(gen.getSpaces().length)); + Space[] spaces = gen.getSpaces(); + for (int j = 0; j < spaces.length; j++) { + Space space = spaces[j]; + assertEquals(SPACE_NAME[i][j], space.getName()); + assertEquals(SPACE_CAPS[i][j], (Long) space.getCapacity()); + assertEquals(SPACE_MAX_CAPS[i][j], (Long) space.getMaxCapacity()); + assertEquals(SPACE_USED[i][j], (Long) space.getUsed()); + } + } + } +} diff -r 9e6bcfc40ea1 -r 0ba74f790a8a vm-memory/client-core/pom.xml --- a/vm-memory/client-core/pom.xml Mon Jan 07 15:48:38 2013 -0500 +++ b/vm-memory/client-core/pom.xml Mon Jan 07 15:50:03 2013 -0500 @@ -67,6 +67,11 @@ com.redhat.thermostat + thermostat-vm-memory-common + ${project.version} + + + com.redhat.thermostat thermostat-client-core ${project.version} diff -r 9e6bcfc40ea1 -r 0ba74f790a8a vm-memory/client-core/src/main/java/com/redhat/thermostat/vm/memory/client/core/MemoryStatsService.java --- a/vm-memory/client-core/src/main/java/com/redhat/thermostat/vm/memory/client/core/MemoryStatsService.java Mon Jan 07 15:48:38 2013 -0500 +++ b/vm-memory/client-core/src/main/java/com/redhat/thermostat/vm/memory/client/core/MemoryStatsService.java Mon Jan 07 15:50:03 2013 -0500 @@ -43,11 +43,11 @@ import com.redhat.thermostat.common.ApplicationService; import com.redhat.thermostat.common.dao.AgentInfoDAO; import com.redhat.thermostat.common.dao.VmInfoDAO; -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; import com.redhat.thermostat.vm.memory.client.core.internal.MemoryStatsController; +import com.redhat.thermostat.vm.memory.common.VmMemoryStatDAO; public class MemoryStatsService implements InformationService { diff -r 9e6bcfc40ea1 -r 0ba74f790a8a vm-memory/client-core/src/main/java/com/redhat/thermostat/vm/memory/client/core/internal/Activator.java --- a/vm-memory/client-core/src/main/java/com/redhat/thermostat/vm/memory/client/core/internal/Activator.java Mon Jan 07 15:48:38 2013 -0500 +++ b/vm-memory/client-core/src/main/java/com/redhat/thermostat/vm/memory/client/core/internal/Activator.java Mon Jan 07 15:50:03 2013 -0500 @@ -51,10 +51,10 @@ import com.redhat.thermostat.common.MultipleServiceTracker.Action; import com.redhat.thermostat.common.dao.AgentInfoDAO; import com.redhat.thermostat.common.dao.VmInfoDAO; -import com.redhat.thermostat.common.dao.VmMemoryStatDAO; import com.redhat.thermostat.common.dao.VmRef; import com.redhat.thermostat.gc.remote.common.GCRequest; import com.redhat.thermostat.vm.memory.client.core.MemoryStatsService; +import com.redhat.thermostat.vm.memory.common.VmMemoryStatDAO; public class Activator implements BundleActivator { diff -r 9e6bcfc40ea1 -r 0ba74f790a8a vm-memory/client-core/src/main/java/com/redhat/thermostat/vm/memory/client/core/internal/MemoryStatsController.java --- a/vm-memory/client-core/src/main/java/com/redhat/thermostat/vm/memory/client/core/internal/MemoryStatsController.java Mon Jan 07 15:48:38 2013 -0500 +++ b/vm-memory/client-core/src/main/java/com/redhat/thermostat/vm/memory/client/core/internal/MemoryStatsController.java Mon Jan 07 15:50:03 2013 -0500 @@ -49,8 +49,8 @@ import com.redhat.thermostat.common.ApplicationService; import com.redhat.thermostat.common.NotImplementedException; import com.redhat.thermostat.common.Size; +import com.redhat.thermostat.common.Size.Unit; import com.redhat.thermostat.common.Timer; -import com.redhat.thermostat.common.Size.Unit; import com.redhat.thermostat.common.Timer.SchedulingType; import com.redhat.thermostat.common.command.Request; import com.redhat.thermostat.common.command.RequestResponseListener; @@ -58,7 +58,6 @@ import com.redhat.thermostat.common.command.Response.ResponseType; import com.redhat.thermostat.common.dao.AgentInfoDAO; import com.redhat.thermostat.common.dao.VmInfoDAO; -import com.redhat.thermostat.common.dao.VmMemoryStatDAO; import com.redhat.thermostat.common.dao.VmRef; import com.redhat.thermostat.common.locale.Translate; import com.redhat.thermostat.gc.remote.common.GCRequest; @@ -71,6 +70,7 @@ import com.redhat.thermostat.vm.memory.client.core.Payload; import com.redhat.thermostat.vm.memory.client.core.StatsModel; import com.redhat.thermostat.vm.memory.client.locale.LocaleResources; +import com.redhat.thermostat.vm.memory.common.VmMemoryStatDAO; public class MemoryStatsController implements InformationServiceController { diff -r 9e6bcfc40ea1 -r 0ba74f790a8a vm-memory/client-core/src/test/java/com/redhat/thermostat/vm/memory/client/core/internal/ActivatorTest.java --- a/vm-memory/client-core/src/test/java/com/redhat/thermostat/vm/memory/client/core/internal/ActivatorTest.java Mon Jan 07 15:48:38 2013 -0500 +++ b/vm-memory/client-core/src/test/java/com/redhat/thermostat/vm/memory/client/core/internal/ActivatorTest.java Mon Jan 07 15:50:03 2013 -0500 @@ -47,10 +47,10 @@ import com.redhat.thermostat.common.ApplicationService; import com.redhat.thermostat.common.dao.AgentInfoDAO; import com.redhat.thermostat.common.dao.VmInfoDAO; -import com.redhat.thermostat.common.dao.VmMemoryStatDAO; import com.redhat.thermostat.gc.remote.common.GCRequest; import com.redhat.thermostat.test.StubBundleContext; import com.redhat.thermostat.vm.memory.client.core.MemoryStatsService; +import com.redhat.thermostat.vm.memory.common.VmMemoryStatDAO; public class ActivatorTest { diff -r 9e6bcfc40ea1 -r 0ba74f790a8a vm-memory/client-core/src/test/java/com/redhat/thermostat/vm/memory/client/core/internal/MemoryStatsControllerTest.java --- a/vm-memory/client-core/src/test/java/com/redhat/thermostat/vm/memory/client/core/internal/MemoryStatsControllerTest.java Mon Jan 07 15:48:38 2013 -0500 +++ b/vm-memory/client-core/src/test/java/com/redhat/thermostat/vm/memory/client/core/internal/MemoryStatsControllerTest.java Mon Jan 07 15:50:03 2013 -0500 @@ -67,7 +67,6 @@ import com.redhat.thermostat.common.command.RequestResponseListener; import com.redhat.thermostat.common.dao.AgentInfoDAO; import com.redhat.thermostat.common.dao.VmInfoDAO; -import com.redhat.thermostat.common.dao.VmMemoryStatDAO; import com.redhat.thermostat.common.dao.VmRef; import com.redhat.thermostat.gc.remote.common.GCRequest; import com.redhat.thermostat.gc.remote.common.command.GCCommand; @@ -78,6 +77,7 @@ import com.redhat.thermostat.vm.memory.client.core.MemoryStatsView; import com.redhat.thermostat.vm.memory.client.core.MemoryStatsViewProvider; import com.redhat.thermostat.vm.memory.client.core.Payload; +import com.redhat.thermostat.vm.memory.common.VmMemoryStatDAO; public class MemoryStatsControllerTest { diff -r 9e6bcfc40ea1 -r 0ba74f790a8a vm-memory/common/pom.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-memory/common/pom.xml Mon Jan 07 15:50:03 2013 -0500 @@ -0,0 +1,68 @@ + + + 4.0.0 + + thermostat-vm-memory + com.redhat.thermostat + 0.5.0-SNAPSHOT + + thermostat-vm-memory-common + bundle + Thermostat VM Memory Common plugin + + + + org.apache.felix + maven-bundle-plugin + true + + + Red Hat, Inc. + com.redhat.thermostat.vm.memory.common + com.redhat.thermostat.vm.memory.common.internal.Activator + + com.redhat.thermostat.vm.memory.common + + + com.redhat.thermostat.vm.memory.common.internal + + + <_nouses>true + + + + + + + + junit + junit + test + + + org.mockito + mockito-core + test + + + org.osgi + org.osgi.core + provided + + + org.osgi + org.osgi.compendium + provided + + + com.redhat.thermostat + thermostat-common-core + ${project.version} + + + com.redhat.thermostat + thermostat-storage-core + ${project.version} + + + diff -r 9e6bcfc40ea1 -r 0ba74f790a8a vm-memory/common/src/main/java/com/redhat/thermostat/vm/memory/common/VmMemoryStatDAO.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-memory/common/src/main/java/com/redhat/thermostat/vm/memory/common/VmMemoryStatDAO.java Mon Jan 07 15:50:03 2013 -0500 @@ -0,0 +1,60 @@ +/* + * 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 + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.memory.common; + +import java.util.List; + +import com.redhat.thermostat.common.dao.VmRef; +import com.redhat.thermostat.storage.core.Category; +import com.redhat.thermostat.storage.core.Key; +import com.redhat.thermostat.storage.model.VmMemoryStat; +import com.redhat.thermostat.storage.model.VmMemoryStat.Generation; + +public interface VmMemoryStatDAO { + + static final Key generationsKey = new Key<>("generations", false); + + static final Category vmMemoryStatsCategory = new Category("vm-memory-stats", + Key.AGENT_ID, Key.VM_ID, Key.TIMESTAMP, generationsKey); + + public VmMemoryStat getLatestMemoryStat(VmRef ref); + + public List getLatestVmMemoryStats(VmRef vm, long since); + + public void putVmMemoryStat(VmMemoryStat stat); + +} diff -r 9e6bcfc40ea1 -r 0ba74f790a8a vm-memory/common/src/main/java/com/redhat/thermostat/vm/memory/common/internal/Activator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-memory/common/src/main/java/com/redhat/thermostat/vm/memory/common/internal/Activator.java Mon Jan 07 15:50:03 2013 -0500 @@ -0,0 +1,79 @@ +/* + * Copyright 2013 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 + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.memory.common.internal; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; +import org.osgi.framework.ServiceRegistration; +import org.osgi.util.tracker.ServiceTracker; + +import com.redhat.thermostat.storage.core.Storage; +import com.redhat.thermostat.vm.memory.common.VmMemoryStatDAO; + +public class Activator implements BundleActivator { + + private ServiceTracker tracker; + private ServiceRegistration reg; + + @Override + public void start(BundleContext context) throws Exception { + tracker = new ServiceTracker(context, Storage.class.getName(), null) { + @Override + public Object addingService(ServiceReference reference) { + Storage storage = (Storage) context.getService(reference); + VmMemoryStatDAO vmMemoryStatDao = new VmMemoryStatDAOImpl(storage); + reg = context.registerService(VmMemoryStatDAO.class.getName(), vmMemoryStatDao, null); + return super.addingService(reference); + } + + @Override + public void removedService(ServiceReference reference, + Object service) { + reg.unregister(); + super.removedService(reference, service); + } + }; + tracker.open(); + } + + @Override + public void stop(BundleContext context) throws Exception { + tracker.close(); + } + +} diff -r 9e6bcfc40ea1 -r 0ba74f790a8a vm-memory/common/src/main/java/com/redhat/thermostat/vm/memory/common/internal/VmMemoryStatDAOImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-memory/common/src/main/java/com/redhat/thermostat/vm/memory/common/internal/VmMemoryStatDAOImpl.java Mon Jan 07 15:50:03 2013 -0500 @@ -0,0 +1,87 @@ +/* + * Copyright 2012 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.memory.common.internal; + +import java.util.List; + +import com.redhat.thermostat.common.dao.VmLatestPojoListGetter; +import com.redhat.thermostat.common.dao.VmRef; +import com.redhat.thermostat.storage.core.Cursor; +import com.redhat.thermostat.storage.core.Key; +import com.redhat.thermostat.storage.core.Query; +import com.redhat.thermostat.storage.core.Storage; +import com.redhat.thermostat.storage.core.Query.Criteria; +import com.redhat.thermostat.storage.model.VmMemoryStat; +import com.redhat.thermostat.vm.memory.common.VmMemoryStatDAO; + +class VmMemoryStatDAOImpl implements VmMemoryStatDAO { + + private final Storage storage; + private final VmLatestPojoListGetter getter; + + VmMemoryStatDAOImpl(Storage storage) { + this.storage = storage; + storage.registerCategory(vmMemoryStatsCategory); + getter = new VmLatestPojoListGetter<>(storage, vmMemoryStatsCategory, VmMemoryStat.class); + } + + @Override + public VmMemoryStat getLatestMemoryStat(VmRef ref) { + Query query = storage.createQuery() + .from(vmMemoryStatsCategory) + .where(Key.AGENT_ID, Criteria.EQUALS, ref.getAgent().getAgentId()) + .where(Key.VM_ID, Criteria.EQUALS, ref.getId()) + .sort(Key.TIMESTAMP, Query.SortDirection.DESCENDING) + .limit(1); + Cursor cursor = storage.findAllPojos(query, VmMemoryStat.class); + if (cursor.hasNext()) { + return cursor.next(); + } + return null; + } + + @Override + public void putVmMemoryStat(VmMemoryStat stat) { + storage.putPojo(vmMemoryStatsCategory, false, stat); + } + + @Override + public List getLatestVmMemoryStats(VmRef ref, long since) { + return getter.getLatest(ref, since); + } + +} diff -r 9e6bcfc40ea1 -r 0ba74f790a8a vm-memory/common/src/test/java/com/redhat/thermostat/vm/memory/common/internal/ActivatorTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-memory/common/src/test/java/com/redhat/thermostat/vm/memory/common/internal/ActivatorTest.java Mon Jan 07 15:50:03 2013 -0500 @@ -0,0 +1,84 @@ +/* + * Copyright 2013 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 + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.memory.common.internal; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; + +import org.junit.Test; + +import com.redhat.thermostat.storage.core.Storage; +import com.redhat.thermostat.test.StubBundleContext; +import com.redhat.thermostat.vm.memory.common.VmMemoryStatDAO; + +public class ActivatorTest { + + @Test + public void verifyActivatorDoesNotRegisterServiceOnMissingDeps() throws Exception { + StubBundleContext context = new StubBundleContext(); + + Activator activator = new Activator(); + + activator.start(context); + + assertEquals(0, context.getAllServices().size()); + assertEquals(1, context.getServiceListeners().size()); + + activator.stop(context); + } + + @Test + public void verifyActivatorRegistersServices() throws Exception { + StubBundleContext context = new StubBundleContext(); + Storage storage = mock(Storage.class); + + context.registerService(Storage.class, storage, null); + + Activator activator = new Activator(); + + activator.start(context); + + assertTrue(context.isServiceRegistered(VmMemoryStatDAO.class.getName(), VmMemoryStatDAOImpl.class)); + + activator.stop(context); + + assertEquals(0, context.getServiceListeners().size()); + assertEquals(1, context.getAllServices().size()); + } + +} diff -r 9e6bcfc40ea1 -r 0ba74f790a8a vm-memory/common/src/test/java/com/redhat/thermostat/vm/memory/common/internal/VmMemoryStatDAOTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-memory/common/src/test/java/com/redhat/thermostat/vm/memory/common/internal/VmMemoryStatDAOTest.java Mon Jan 07 15:50:03 2013 -0500 @@ -0,0 +1,202 @@ +/* + * 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 + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.memory.common.internal; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.same; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.redhat.thermostat.common.dao.HostRef; +import com.redhat.thermostat.common.dao.VmRef; +import com.redhat.thermostat.storage.core.Cursor; +import com.redhat.thermostat.storage.core.Key; +import com.redhat.thermostat.storage.core.Query; +import com.redhat.thermostat.storage.core.Storage; +import com.redhat.thermostat.storage.core.Query.Criteria; +import com.redhat.thermostat.storage.model.VmMemoryStat; +import com.redhat.thermostat.storage.model.VmMemoryStat.Generation; +import com.redhat.thermostat.storage.model.VmMemoryStat.Space; +import com.redhat.thermostat.test.MockQuery; +import com.redhat.thermostat.vm.memory.common.VmMemoryStatDAO; +import com.redhat.thermostat.vm.memory.common.internal.VmMemoryStatDAOImpl; + +public class VmMemoryStatDAOTest { + + private static final int VM_ID = 0xcafe; + private static final String AGENT_ID = "agent"; + + private Storage storage; + private VmRef vmRef; + + private MockQuery query; + private Cursor cursor; + + @SuppressWarnings("unchecked") + @Before + public void setUp() { + + + HostRef hostRef = mock(HostRef.class); + when(hostRef.getAgentId()).thenReturn(AGENT_ID); + + vmRef = mock(VmRef.class); + when(vmRef.getAgent()).thenReturn(hostRef); + when(vmRef.getId()).thenReturn(VM_ID); + + storage = mock(Storage.class); + query = new MockQuery(); + when(storage.createQuery()).thenReturn(query); + + cursor = mock(Cursor.class); + when(storage.findAllPojos(any(Query.class), same(VmMemoryStat.class))).thenReturn(cursor); + + when(cursor.hasNext()).thenReturn(false); + + } + + @After + public void tearDown() { + query = null; + vmRef = null; + cursor = null; + storage = null; + } + + @Test + public void testCategories() { + Collection> keys; + + assertEquals("vm-memory-stats", VmMemoryStatDAO.vmMemoryStatsCategory.getName()); + keys = VmMemoryStatDAO.vmMemoryStatsCategory.getKeys(); + assertTrue(keys.contains(new Key<>("agentId", true))); + assertTrue(keys.contains(new Key("vmId", true))); + assertTrue(keys.contains(new Key("timeStamp", false))); + assertTrue(keys.contains(new Key("generations", false))); + assertEquals(4, keys.size()); + } + + @Test + public void testGetLatest() { + VmMemoryStatDAO impl = new VmMemoryStatDAOImpl(storage); + impl.getLatestMemoryStat(vmRef); + + verifyQuery(); + } + + @Test + public void testGetLatestSince() { + VmMemoryStatDAO impl = new VmMemoryStatDAOImpl(storage); + impl.getLatestVmMemoryStats(vmRef, 123); + + verifyQuery(); + + assertTrue(query.hasWhereClause(Key.TIMESTAMP, Criteria.GREATER_THAN, 123l)); + } + + private void verifyQuery() { + + assertTrue(query.hasWhereClause(Key.AGENT_ID, Criteria.EQUALS, AGENT_ID)); + assertTrue(query.hasWhereClause(Key.VM_ID, Criteria.EQUALS, VM_ID)); + assertTrue(query.hasSort(Key.TIMESTAMP, Query.SortDirection.DESCENDING)); + } + + @Test + public void testGetLatestReturnsNullWhenStorageEmpty() { + when(cursor.hasNext()).thenReturn(false); + when(cursor.next()).thenReturn(null); + + Storage storage = mock(Storage.class); + when(storage.createQuery()).thenReturn(new MockQuery()); + when(storage.findAllPojos(any(Query.class), same(VmMemoryStat.class))).thenReturn(cursor); + + VmMemoryStatDAO impl = new VmMemoryStatDAOImpl(storage); + VmMemoryStat latest = impl.getLatestMemoryStat(vmRef); + assertTrue(latest == null); + } + + @Test + public void testPutVmMemoryStat() { + + List generations = new ArrayList(); + + int i = 0; + for (String genName: new String[] { "new", "old", "perm" }) { + Generation gen = new Generation(); + gen.setName(genName); + gen.setCollector(gen.getName()); + generations.add(gen); + List spaces = new ArrayList(); + String[] spaceNames = null; + if (genName.equals("new")) { + spaceNames = new String[] { "eden", "s0", "s1" }; + } else if (genName.equals("old")) { + spaceNames = new String[] { "old" }; + } else { + spaceNames = new String[] { "perm" }; + } + for (String spaceName: spaceNames) { + Space space = new Space(); + space.setName(spaceName); + space.setIndex(0); + space.setUsed(i++); + space.setCapacity(i++); + space.setMaxCapacity(i++); + spaces.add(space); + } + gen.setSpaces(spaces.toArray(new Space[spaces.size()])); + } + VmMemoryStat stat = new VmMemoryStat(1, 2, generations.toArray(new Generation[generations.size()])); + + Storage storage = mock(Storage.class); + VmMemoryStatDAO dao = new VmMemoryStatDAOImpl(storage); + dao.putVmMemoryStat(stat); + + verify(storage).putPojo(VmMemoryStatDAO.vmMemoryStatsCategory, false, stat); + } +} diff -r 9e6bcfc40ea1 -r 0ba74f790a8a vm-memory/pom.xml --- a/vm-memory/pom.xml Mon Jan 07 15:48:38 2013 -0500 +++ b/vm-memory/pom.xml Mon Jan 07 15:50:03 2013 -0500 @@ -51,8 +51,10 @@ Thermostat VM Memory plugin + agent client-core client-swing + common