changeset 197:a0b56e387957

Add getCount() to storage/dao layers where relevant. Also, fixes NPE issues caused by ChunkConverter defect. reviewed-by: neugens, rkennke review-thread: http://icedtea.classpath.org/pipermail/thermostat/2012-April/000679.html
author Jon VanAlten <jon.vanalten@redhat.com>
date Wed, 04 Apr 2012 11:43:38 -0400
parents 585a09251bf6
children d794eace82e8
files agent/src/main/java/com/redhat/thermostat/backend/system/SystemBackend.java agent/src/test/java/com/redhat/thermostat/backend/system/SystemBackendTest.java client/pom.xml client/src/main/java/com/redhat/thermostat/client/Main.java client/src/main/java/com/redhat/thermostat/client/MainWindowControllerImpl.java client/src/main/java/com/redhat/thermostat/client/SummaryPanelFacade.java client/src/main/java/com/redhat/thermostat/client/SummaryPanelFacadeImpl.java client/src/main/java/com/redhat/thermostat/client/UiFacadeFactoryImpl.java client/src/main/java/com/redhat/thermostat/client/ui/SummaryPanel.java client/src/test/java/com/redhat/thermostat/client/MainWindowControllerImplTest.java client/src/test/java/com/redhat/thermostat/client/SummaryPanelFacadeImplTest.java client/src/test/java/com/redhat/thermostat/client/ui/MainWindowTest.java common/src/main/java/com/redhat/thermostat/common/dao/Countable.java common/src/main/java/com/redhat/thermostat/common/dao/CpuStatDAO.java common/src/main/java/com/redhat/thermostat/common/dao/CpuStatDAOImpl.java common/src/main/java/com/redhat/thermostat/common/dao/DAOFactory.java common/src/main/java/com/redhat/thermostat/common/dao/HostInfoDAO.java common/src/main/java/com/redhat/thermostat/common/dao/HostInfoDAOImpl.java common/src/main/java/com/redhat/thermostat/common/dao/HostRefDAO.java common/src/main/java/com/redhat/thermostat/common/dao/HostRefDAOImpl.java common/src/main/java/com/redhat/thermostat/common/dao/MemoryStatDAO.java common/src/main/java/com/redhat/thermostat/common/dao/MemoryStatDAOImpl.java common/src/main/java/com/redhat/thermostat/common/dao/MongoDAOFactory.java common/src/main/java/com/redhat/thermostat/common/dao/NetworkInterfaceInfoDAO.java common/src/main/java/com/redhat/thermostat/common/dao/NetworkInterfaceInfoDAOImpl.java common/src/main/java/com/redhat/thermostat/common/dao/VmClassStatDAO.java common/src/main/java/com/redhat/thermostat/common/dao/VmClassStatDAOImpl.java common/src/main/java/com/redhat/thermostat/common/dao/VmCpuStatDAO.java common/src/main/java/com/redhat/thermostat/common/dao/VmCpuStatDAOImpl.java common/src/main/java/com/redhat/thermostat/common/dao/VmGcStatConverter.java common/src/main/java/com/redhat/thermostat/common/dao/VmGcStatDAO.java common/src/main/java/com/redhat/thermostat/common/dao/VmGcStatDAOImpl.java common/src/main/java/com/redhat/thermostat/common/dao/VmInfoDAO.java common/src/main/java/com/redhat/thermostat/common/dao/VmInfoDAOImpl.java common/src/main/java/com/redhat/thermostat/common/dao/VmMemoryStatDAO.java common/src/main/java/com/redhat/thermostat/common/dao/VmMemoryStatDAOImpl.java common/src/main/java/com/redhat/thermostat/common/dao/VmRefDAO.java common/src/main/java/com/redhat/thermostat/common/dao/VmRefDAOImpl.java common/src/main/java/com/redhat/thermostat/common/storage/ChunkConverter.java common/src/main/java/com/redhat/thermostat/common/storage/MongoStorage.java common/src/main/java/com/redhat/thermostat/common/storage/Storage.java common/src/test/java/com/redhat/thermostat/common/dao/CpuStatDAOTest.java common/src/test/java/com/redhat/thermostat/common/dao/HostInfoDAOTest.java common/src/test/java/com/redhat/thermostat/common/dao/HostRefDAOTest.java common/src/test/java/com/redhat/thermostat/common/dao/MemoryStatDAOTest.java common/src/test/java/com/redhat/thermostat/common/dao/MongoDAOFactoryTest.java common/src/test/java/com/redhat/thermostat/common/dao/NetworkInterfaceInfoDAOTest.java common/src/test/java/com/redhat/thermostat/common/dao/VmClassStatDAOTest.java common/src/test/java/com/redhat/thermostat/common/dao/VmCpuStatDAOTest.java common/src/test/java/com/redhat/thermostat/common/dao/VmGcStatConverterTest.java common/src/test/java/com/redhat/thermostat/common/dao/VmGcStatDAOTest.java common/src/test/java/com/redhat/thermostat/common/dao/VmInfoDAOTest.java common/src/test/java/com/redhat/thermostat/common/dao/VmMemoryStatDAOTest.java common/src/test/java/com/redhat/thermostat/common/dao/VmRefDAOTest.java common/src/test/java/com/redhat/thermostat/common/storage/MongoStorageTest.java
diffstat 55 files changed, 492 insertions(+), 694 deletions(-) [+]
line wrap: on
line diff
--- a/agent/src/main/java/com/redhat/thermostat/backend/system/SystemBackend.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/agent/src/main/java/com/redhat/thermostat/backend/system/SystemBackend.java	Wed Apr 04 11:43:38 2012 -0400
@@ -102,7 +102,7 @@
         categories.add(NetworkInterfaceInfoDAO.networkInfoCategory);
         categories.add(VmClassStatDAO.vmClassStatsCategory);
         categories.add(VmCpuStatDAO.vmCpuStatCategory);
-        categories.add(VmGcStatDAO.vmGcStatsCategory);
+        categories.add(VmGcStatDAO.vmGcStatCategory);
         categories.add(VmInfoDAO.vmInfoCategory);
         categories.add(VmMemoryStatDAO.vmMemoryStatsCategory);
 
--- a/agent/src/test/java/com/redhat/thermostat/backend/system/SystemBackendTest.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/agent/src/test/java/com/redhat/thermostat/backend/system/SystemBackendTest.java	Wed Apr 04 11:43:38 2012 -0400
@@ -101,7 +101,7 @@
         assertTrue(categories.contains(NetworkInterfaceInfoDAO.networkInfoCategory));
         assertTrue(categories.contains(VmClassStatDAO.vmClassStatsCategory));
         assertTrue(categories.contains(VmCpuStatDAO.vmCpuStatCategory));
-        assertTrue(categories.contains(VmGcStatDAO.vmGcStatsCategory));
+        assertTrue(categories.contains(VmGcStatDAO.vmGcStatCategory));
         assertTrue(categories.contains(VmInfoDAO.vmInfoCategory));
         assertTrue(categories.contains(VmMemoryStatDAO.vmMemoryStatsCategory));
     }
--- a/client/pom.xml	Wed Apr 04 14:48:12 2012 +0200
+++ b/client/pom.xml	Wed Apr 04 11:43:38 2012 -0400
@@ -76,10 +76,6 @@
       <groupId>org.jfree</groupId>
       <artifactId>jfreechart</artifactId>
     </dependency>
-    <dependency>
-      <groupId>org.mongodb</groupId>
-      <artifactId>mongo-java-driver</artifactId>
-    </dependency>
   </dependencies>
 
 </project>
--- a/client/src/main/java/com/redhat/thermostat/client/Main.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/client/src/main/java/com/redhat/thermostat/client/Main.java	Wed Apr 04 11:43:38 2012 -0400
@@ -52,9 +52,7 @@
 import com.redhat.thermostat.client.locale.LocaleResources;
 import com.redhat.thermostat.client.ui.ConnectionSelectionDialog;
 import com.redhat.thermostat.client.ui.LayoutDebugHelper;
-import com.redhat.thermostat.client.ui.MainWindow;
 import com.redhat.thermostat.common.Constants;
-import com.redhat.thermostat.common.LaunchException;
 import com.redhat.thermostat.common.ThreadPoolTimerFactory;
 import com.redhat.thermostat.common.TimerFactory;
 import com.redhat.thermostat.common.config.StartupConfiguration;
@@ -63,7 +61,6 @@
 import com.redhat.thermostat.common.dao.Connection.ConnectionStatus;
 import com.redhat.thermostat.common.dao.ConnectionProvider;
 import com.redhat.thermostat.common.dao.DAOFactory;
-import com.redhat.thermostat.common.dao.MongoConnection;
 import com.redhat.thermostat.common.dao.MongoConnectionProvider;
 import com.redhat.thermostat.common.dao.MongoDAOFactory;
 import com.redhat.thermostat.common.utils.LoggingUtils;
@@ -123,7 +120,7 @@
         connection.connect();
         connection.removeListener(connectionListener);
 
-        uiFacadeFactory = new UiFacadeFactoryImpl((MongoConnection) connection);
+        uiFacadeFactory = new UiFacadeFactoryImpl();
 
         MainWindowController mainController = uiFacadeFactory.getMainWindow();
         mainController.showMainMainWindow();
--- a/client/src/main/java/com/redhat/thermostat/client/MainWindowControllerImpl.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/client/src/main/java/com/redhat/thermostat/client/MainWindowControllerImpl.java	Wed Apr 04 11:43:38 2012 -0400
@@ -45,10 +45,10 @@
 import com.redhat.thermostat.common.ActionListener;
 import com.redhat.thermostat.common.Timer;
 import com.redhat.thermostat.common.dao.DAOFactory;
+import com.redhat.thermostat.common.dao.HostInfoDAO;
 import com.redhat.thermostat.common.dao.HostRef;
-import com.redhat.thermostat.common.dao.HostRefDAO;
+import com.redhat.thermostat.common.dao.VmInfoDAO;
 import com.redhat.thermostat.common.dao.VmRef;
-import com.redhat.thermostat.common.dao.VmRefDAO;
 import com.redhat.thermostat.common.utils.LoggingUtils;
 
 public class MainWindowControllerImpl implements MainWindowController {
@@ -59,15 +59,15 @@
 
     private String filter;
 
-    private HostRefDAO hostRefDAO;
-    private VmRefDAO vmRefDAO;
+    private final HostInfoDAO hostsDAO;
+    private final VmInfoDAO vmsDAO;
 
     public MainWindowControllerImpl(MainView view) {
 
         ApplicationContext ctx = ApplicationContext.getInstance();
         DAOFactory daoFactory = ctx.getDAOFactory();
-        hostRefDAO = daoFactory.getHostRefDAO();
-        vmRefDAO = daoFactory.getVmRefDAO();
+        hostsDAO = daoFactory.getHostInfoDAO();
+        vmsDAO = daoFactory.getVmInfoDAO();
 
         initView(view);
         initializeTimer();
@@ -78,12 +78,12 @@
 
         @Override
         public Collection<HostRef> getHosts() {
-            return hostRefDAO.getHosts();
+            return hostsDAO.getHosts();
         }
 
         @Override
         public Collection<VmRef> getVMs(HostRef host) {
-            return vmRefDAO.getVMs(host);
+            return vmsDAO.getVMs(host);
         }
         
     }
--- a/client/src/main/java/com/redhat/thermostat/client/SummaryPanelFacade.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/client/src/main/java/com/redhat/thermostat/client/SummaryPanelFacade.java	Wed Apr 04 11:43:38 2012 -0400
@@ -40,9 +40,9 @@
 
 public interface SummaryPanelFacade extends AsyncUiFacade {
 
-    public ChangeableText getTotalConnectedVms();
+    public ChangeableText getTotalMonitoredVms();
 
-    public ChangeableText getTotalConnectedAgents();
+    public ChangeableText getTotalMonitoredHosts();
 
     public List<String> getIssues();
 
--- a/client/src/main/java/com/redhat/thermostat/client/SummaryPanelFacadeImpl.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/client/src/main/java/com/redhat/thermostat/client/SummaryPanelFacadeImpl.java	Wed Apr 04 11:43:38 2012 -0400
@@ -40,36 +40,40 @@
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 
-import com.mongodb.DB;
-import com.mongodb.DBCollection;
 import com.redhat.thermostat.client.appctx.ApplicationContext;
 import com.redhat.thermostat.common.Timer;
 import com.redhat.thermostat.common.Timer.SchedulingType;
+import com.redhat.thermostat.common.dao.DAOFactory;
+import com.redhat.thermostat.common.dao.HostInfoDAO;
+import com.redhat.thermostat.common.dao.VmInfoDAO;
 
 public class SummaryPanelFacadeImpl implements SummaryPanelFacade {
 
-    private final DBCollection agentConfigCollection;
-    private final DBCollection vmInfoCollection;
+    private final HostInfoDAO hostsDAO;
+    private final VmInfoDAO vmsDAO;
 
-    private final ChangeableText connectedAgentText;
-    private final ChangeableText connectedVmText;
+    private final ChangeableText totalHostsText;
+    private final ChangeableText totalVmsText;
 
     private final Timer backgroundUpdateTimer;
 
-    public SummaryPanelFacadeImpl(DB db) {
-        this.agentConfigCollection = db.getCollection("agent-config");
-        this.vmInfoCollection = db.getCollection("vm-info");
+    public SummaryPanelFacadeImpl() {
+        
+        ApplicationContext ctx = ApplicationContext.getInstance();
+        DAOFactory daoFactory = ctx.getDAOFactory();
+        hostsDAO = daoFactory.getHostInfoDAO();
+        vmsDAO = daoFactory.getVmInfoDAO();
 
-        this.connectedVmText = new ChangeableText("");
-        this.connectedAgentText = new ChangeableText("");
+        this.totalVmsText = new ChangeableText("");
+        this.totalHostsText = new ChangeableText("");
 
         backgroundUpdateTimer = ApplicationContext.getInstance().getTimerFactory().createTimer();
         backgroundUpdateTimer.setAction(new Runnable() {
             
             @Override
             public void run() {
-                connectedVmText.setText(String.valueOf(vmInfoCollection.getCount()));
-                connectedAgentText.setText(String.valueOf(agentConfigCollection.getCount()));
+                totalVmsText.setText(String.valueOf(vmsDAO.getCount()));
+                totalHostsText.setText(String.valueOf(hostsDAO.getCount()));
             }
         });
         backgroundUpdateTimer.setInitialDelay(0);
@@ -89,13 +93,13 @@
     }
 
     @Override
-    public ChangeableText getTotalConnectedVms() {
-        return connectedVmText;
+    public ChangeableText getTotalMonitoredVms() {
+        return totalVmsText;
     }
 
     @Override
-    public ChangeableText getTotalConnectedAgents() {
-        return connectedAgentText;
+    public ChangeableText getTotalMonitoredHosts() {
+        return totalHostsText;
     }
 
     @Override
--- a/client/src/main/java/com/redhat/thermostat/client/UiFacadeFactoryImpl.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/client/src/main/java/com/redhat/thermostat/client/UiFacadeFactoryImpl.java	Wed Apr 04 11:43:38 2012 -0400
@@ -38,18 +38,10 @@
 
 import com.redhat.thermostat.client.ui.MainWindow;
 import com.redhat.thermostat.common.dao.HostRef;
-import com.redhat.thermostat.common.dao.MongoConnection;
 import com.redhat.thermostat.common.dao.VmRef;
 
 public class UiFacadeFactoryImpl implements UiFacadeFactory {
 
-    // TODO: Eventually, this should disappear and be completely provided by the DAOFactory.
-    private MongoConnection connection;
-
-    public UiFacadeFactoryImpl(MongoConnection connection) {
-        this.connection = connection;
-    }
-
     @Override
     public MainWindowController getMainWindow() {
         MainView mainView = new MainWindow(this);
@@ -58,7 +50,7 @@
 
     @Override
     public SummaryPanelFacade getSummaryPanel() {
-        return new SummaryPanelFacadeImpl(connection.getDB());
+        return new SummaryPanelFacadeImpl();
 
     }
 
--- a/client/src/main/java/com/redhat/thermostat/client/ui/SummaryPanel.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/client/src/main/java/com/redhat/thermostat/client/ui/SummaryPanel.java	Wed Apr 04 11:43:38 2012 -0400
@@ -70,9 +70,9 @@
         Section summarySection = new Section(localize(LocaleResources.HOME_PANEL_SECTION_SUMMARY));
         sections.add(summarySection);
 
-        entry = new TableEntry(localize(LocaleResources.HOME_PANEL_TOTAL_MACHINES), this.facade.getTotalConnectedAgents());
+        entry = new TableEntry(localize(LocaleResources.HOME_PANEL_TOTAL_MACHINES), this.facade.getTotalMonitoredHosts());
         summarySection.add(entry);
-        entry = new TableEntry(localize(LocaleResources.HOME_PANEL_TOTAL_JVMS), this.facade.getTotalConnectedVms());
+        entry = new TableEntry(localize(LocaleResources.HOME_PANEL_TOTAL_JVMS), this.facade.getTotalMonitoredVms());
         summarySection.add(entry);
 
         SimpleTable simpleTable = new SimpleTable();
--- a/client/src/test/java/com/redhat/thermostat/client/MainWindowControllerImplTest.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/client/src/test/java/com/redhat/thermostat/client/MainWindowControllerImplTest.java	Wed Apr 04 11:43:38 2012 -0400
@@ -61,10 +61,10 @@
 import com.redhat.thermostat.common.Timer;
 import com.redhat.thermostat.common.TimerFactory;
 import com.redhat.thermostat.common.dao.DAOFactory;
+import com.redhat.thermostat.common.dao.HostInfoDAO;
 import com.redhat.thermostat.common.dao.HostRef;
-import com.redhat.thermostat.common.dao.HostRefDAO;
+import com.redhat.thermostat.common.dao.VmInfoDAO;
 import com.redhat.thermostat.common.dao.VmRef;
-import com.redhat.thermostat.common.dao.VmRefDAO;
 
 public class MainWindowControllerImplTest {
 
@@ -76,8 +76,8 @@
 
     private Timer mainWindowTimer;
 
-    private HostRefDAO mockHostRefDAO;
-    private VmRefDAO mockVmRefDAO;
+    private HostInfoDAO mockHostsDAO;
+    private VmInfoDAO mockVmsDAO;
 
     @Before
     public void setUp() {
@@ -98,13 +98,13 @@
     }
 
     private void setupDAOs() {
-        mockHostRefDAO = mock(HostRefDAO.class);
+        mockHostsDAO = mock(HostInfoDAO.class);
 
-        mockVmRefDAO = mock(VmRefDAO.class);
+        mockVmsDAO = mock(VmInfoDAO.class);
 
         DAOFactory daoFactory = mock(DAOFactory.class);
-        when(daoFactory.getHostRefDAO()).thenReturn(mockHostRefDAO);
-        when(daoFactory.getVmRefDAO()).thenReturn(mockVmRefDAO);
+        when(daoFactory.getHostInfoDAO()).thenReturn(mockHostsDAO);
+        when(daoFactory.getVmInfoDAO()).thenReturn(mockVmsDAO);
         ApplicationContext.getInstance().setDAOFactory(daoFactory);
 
     }
@@ -113,8 +113,8 @@
     public void tearDown() {
         view = null;
         controller = null;
-        mockHostRefDAO = null;
-        mockVmRefDAO = null;
+        mockHostsDAO = null;
+        mockVmsDAO = null;
         l = null;
         ApplicationContextUtil.resetApplicationContext();
     }
@@ -157,7 +157,7 @@
         expectedHosts.add(new HostRef("123", "fluffhost1"));
         expectedHosts.add(new HostRef("456", "fluffhost2"));
 
-        when(mockHostRefDAO.getHosts()).thenReturn(expectedHosts);
+        when(mockHostsDAO.getHosts()).thenReturn(expectedHosts);
 
         controller.doUpdateTreeAsync();
 
@@ -177,7 +177,7 @@
         expectedVMs.add(new VmRef(host, 123, "vm1"));
         expectedVMs.add(new VmRef(host, 456, "vm2"));
 
-        when(mockVmRefDAO.getVMs(any(HostRef.class))).thenReturn(expectedVMs);
+        when(mockVmsDAO.getVMs(any(HostRef.class))).thenReturn(expectedVMs);
 
         controller.doUpdateTreeAsync();
 
--- a/client/src/test/java/com/redhat/thermostat/client/SummaryPanelFacadeImplTest.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/client/src/test/java/com/redhat/thermostat/client/SummaryPanelFacadeImplTest.java	Wed Apr 04 11:43:38 2012 -0400
@@ -47,12 +47,15 @@
 import org.junit.Before;
 import org.junit.Test;
 
-import com.mongodb.DB;
 import com.redhat.thermostat.client.appctx.ApplicationContext;
 import com.redhat.thermostat.client.appctx.ApplicationContextUtil;
 import com.redhat.thermostat.common.Timer;
 import com.redhat.thermostat.common.Timer.SchedulingType;
 import com.redhat.thermostat.common.TimerFactory;
+import com.redhat.thermostat.common.dao.DAOFactory;
+import com.redhat.thermostat.common.dao.HostInfoDAO;
+import com.redhat.thermostat.common.dao.MongoDAOFactory;
+import com.redhat.thermostat.common.dao.VmInfoDAO;
 
 public class SummaryPanelFacadeImplTest {
 
@@ -64,7 +67,17 @@
         timer = mock(Timer.class);
         TimerFactory timerFactory = mock(TimerFactory.class);
         when(timerFactory.createTimer()).thenReturn(timer);
-        ApplicationContext.getInstance().setTimerFactory(timerFactory);
+        ApplicationContext ctx = ApplicationContext.getInstance();
+        ctx.setTimerFactory(timerFactory);
+
+        HostInfoDAO hDAO = mock(HostInfoDAO.class);
+        VmInfoDAO vDAO = mock(VmInfoDAO.class);
+
+        DAOFactory daoFactory = mock(MongoDAOFactory.class);
+        when(daoFactory.getHostInfoDAO()).thenReturn(hDAO);
+        when(daoFactory.getVmInfoDAO()).thenReturn(vDAO);
+
+        ctx.setDAOFactory(daoFactory);
     }
 
     @After
@@ -76,9 +89,7 @@
     @Test
     public void testTimer() {
 
-        DB db = mock(DB.class);
-
-        SummaryPanelFacadeImpl summaryPanelCtrl = new SummaryPanelFacadeImpl(db);
+        SummaryPanelFacadeImpl summaryPanelCtrl = new SummaryPanelFacadeImpl();
         summaryPanelCtrl.start();
 
         verify(timer).setAction(isNotNull(Runnable.class));
--- a/client/src/test/java/com/redhat/thermostat/client/ui/MainWindowTest.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/client/src/test/java/com/redhat/thermostat/client/ui/MainWindowTest.java	Wed Apr 04 11:43:38 2012 -0400
@@ -98,8 +98,8 @@
     public void setUp() {
 
         SummaryPanelFacade summaryPanelFacade = mock(SummaryPanelFacade.class);
-        when(summaryPanelFacade.getTotalConnectedAgents()).thenReturn(new ChangeableText("totalConnectedAgents"));
-        when(summaryPanelFacade.getTotalConnectedVms()).thenReturn(new ChangeableText("connectedVms"));
+        when(summaryPanelFacade.getTotalMonitoredHosts()).thenReturn(new ChangeableText("totalConnectedAgents"));
+        when(summaryPanelFacade.getTotalMonitoredVms()).thenReturn(new ChangeableText("connectedVms"));
 
         UiFacadeFactory uiFacadeFactory = mock(UiFacadeFactory.class);
         when(uiFacadeFactory.getSummaryPanel()).thenReturn(summaryPanelFacade);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/src/main/java/com/redhat/thermostat/common/dao/Countable.java	Wed Apr 04 11:43:38 2012 -0400
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.common.dao;
+
+interface Countable {
+
+    public long getCount();
+
+}
--- a/common/src/main/java/com/redhat/thermostat/common/dao/CpuStatDAO.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/common/src/main/java/com/redhat/thermostat/common/dao/CpuStatDAO.java	Wed Apr 04 11:43:38 2012 -0400
@@ -42,14 +42,15 @@
 import com.redhat.thermostat.common.storage.Category;
 import com.redhat.thermostat.common.storage.Key;
 
-public interface CpuStatDAO {
+public interface CpuStatDAO extends Countable {
 
     static Key<Double> cpu5LoadKey = new Key<>("5load", false);
     static Key<Double> cpu10LoadKey = new Key<>("10load", false);
     static Key<Double> cpu15LoadKey = new Key<>("15load", false);
 
     static final Category cpuStatCategory = new Category("cpu-stats",
-            Key.TIMESTAMP, cpu5LoadKey, cpu10LoadKey, cpu15LoadKey);
+            Key.AGENT_ID, Key.TIMESTAMP, cpu5LoadKey, cpu10LoadKey, cpu15LoadKey);
 
     List<CpuStat> getLatestCpuStats(HostRef ref);
+
 }
--- a/common/src/main/java/com/redhat/thermostat/common/dao/CpuStatDAOImpl.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/common/src/main/java/com/redhat/thermostat/common/dao/CpuStatDAOImpl.java	Wed Apr 04 11:43:38 2012 -0400
@@ -59,10 +59,14 @@
     public List<CpuStat> getLatestCpuStats(HostRef ref) {
         HostLatestPojoListGetter<CpuStat> getter = getters.get(ref);
         if (getter == null) {
-            getter = new HostLatestPojoListGetter<CpuStat>(storage, CpuStatDAO.cpuStatCategory, converter, ref);
+            getter = new HostLatestPojoListGetter<CpuStat>(storage, cpuStatCategory, converter, ref);
             getters.put(ref, getter);
         }
         return getter.getLatest();
     }
 
+    @Override
+    public long getCount() {
+        return storage.getCount(cpuStatCategory);
+    }
 }
--- a/common/src/main/java/com/redhat/thermostat/common/dao/DAOFactory.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/common/src/main/java/com/redhat/thermostat/common/dao/DAOFactory.java	Wed Apr 04 11:43:38 2012 -0400
@@ -61,8 +61,4 @@
 
     public VmGcStatDAO getVmGcStatDAO();
 
-    public HostRefDAO getHostRefDAO();
-
-    public VmRefDAO getVmRefDAO();
-
 }
--- a/common/src/main/java/com/redhat/thermostat/common/dao/HostInfoDAO.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/common/src/main/java/com/redhat/thermostat/common/dao/HostInfoDAO.java	Wed Apr 04 11:43:38 2012 -0400
@@ -36,11 +36,13 @@
 
 package com.redhat.thermostat.common.dao;
 
+import java.util.Collection;
+
 import com.redhat.thermostat.common.model.HostInfo;
 import com.redhat.thermostat.common.storage.Category;
 import com.redhat.thermostat.common.storage.Key;
 
-public interface HostInfoDAO {
+public interface HostInfoDAO extends Countable {
 
     static Key<String> hostNameKey = new Key<>("hostname", true);
     static Key<String> osNameKey = new Key<>("os_name", false);
@@ -50,8 +52,10 @@
     static Key<Long> hostMemoryTotalKey = new Key<>("memory_total", false);
 
     static final Category hostInfoCategory = new Category("host-info",
-            hostNameKey, osNameKey, osKernelKey,
+            Key.AGENT_ID, hostNameKey, osNameKey, osKernelKey,
             cpuCountKey, cpuModelKey, hostMemoryTotalKey);
 
     HostInfo getHostInfo(HostRef ref);
+
+    Collection<HostRef> getHosts();
 }
--- a/common/src/main/java/com/redhat/thermostat/common/dao/HostInfoDAOImpl.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/common/src/main/java/com/redhat/thermostat/common/dao/HostInfoDAOImpl.java	Wed Apr 04 11:43:38 2012 -0400
@@ -36,8 +36,12 @@
 
 package com.redhat.thermostat.common.dao;
 
+import java.util.ArrayList;
+import java.util.Collection;
+
 import com.redhat.thermostat.common.model.HostInfo;
 import com.redhat.thermostat.common.storage.Chunk;
+import com.redhat.thermostat.common.storage.Cursor;
 import com.redhat.thermostat.common.storage.Key;
 import com.redhat.thermostat.common.storage.Storage;
 
@@ -52,9 +56,27 @@
 
     @Override
     public HostInfo getHostInfo(HostRef ref) {
-        Chunk query = new Chunk(HostInfoDAO.hostInfoCategory, false);
+        Chunk query = new Chunk(hostInfoCategory, false);
         query.put(Key.AGENT_ID, ref.getAgentId());
         Chunk result = storage.find(query);
         return result == null ? null : converter.fromChunk(result);
     }
+
+    @Override
+    public Collection<HostRef> getHosts() {
+        Collection<HostRef> hosts = new ArrayList<HostRef>();
+        Cursor hostsCursor = storage.findAllFromCategory(hostInfoCategory);
+        while(hostsCursor.hasNext()) {
+            Chunk hostChunk = hostsCursor.next();
+            String agentId = hostChunk.get(Key.AGENT_ID);
+            String hostName = hostChunk.get(hostNameKey);
+            hosts.add(new HostRef(agentId, hostName));
+        }
+        return hosts;
+    }
+
+    @Override
+    public long getCount() {
+        return storage.getCount(hostInfoCategory);
+    }
 }
--- a/common/src/main/java/com/redhat/thermostat/common/dao/HostRefDAO.java	Wed Apr 04 14:48:12 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.common.dao;
-
-import java.util.Collection;
-
-import com.redhat.thermostat.common.storage.Category;
-import com.redhat.thermostat.common.storage.Key;
-
-public interface HostRefDAO {
-
-    static final Key<String> agentIdKey = new Key<>("agent-id", false);
-    static final Category agentConfigCategory = new Category("agent-config", agentIdKey);
-
-    Collection<HostRef> getHosts();
-
-}
--- a/common/src/main/java/com/redhat/thermostat/common/dao/HostRefDAOImpl.java	Wed Apr 04 14:48:12 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.common.dao;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
-import com.redhat.thermostat.common.storage.Chunk;
-import com.redhat.thermostat.common.storage.Cursor;
-import com.redhat.thermostat.common.storage.Storage;
-
-class HostRefDAOImpl implements HostRefDAO {
-
-    private Storage storage;
-
-    HostRefDAOImpl(Storage storage) {
-        this.storage = storage;
-    }
-
-    @Override
-    public Collection<HostRef> getHosts() {
-        Collection<HostRef> hosts = new ArrayList<HostRef>();
-        Cursor agentsCursor = storage.findAllFromCategory(agentConfigCategory);
-        while (agentsCursor.hasNext()) {
-            Chunk agentConfig = agentsCursor.next();
-            HostRef host = getHostFromAgent(agentConfig);
-            hosts.add(host);
-        }
-        return hosts;
-    }
-
-    private HostRef getHostFromAgent(Chunk agentConfig) {
-        String agentId = agentConfig.get(agentIdKey);
-        Chunk hostQuery = new Chunk(HostInfoDAO.hostInfoCategory, false);
-        hostQuery.put(agentIdKey, agentId);
-        Chunk host = storage.find(hostQuery);
-        String hostname = host.get(HostInfoDAO.hostNameKey);
-        return new HostRef(agentId, hostname);
-    }
-
-}
--- a/common/src/main/java/com/redhat/thermostat/common/dao/MemoryStatDAO.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/common/src/main/java/com/redhat/thermostat/common/dao/MemoryStatDAO.java	Wed Apr 04 11:43:38 2012 -0400
@@ -42,7 +42,7 @@
 import com.redhat.thermostat.common.storage.Category;
 import com.redhat.thermostat.common.storage.Key;
 
-public interface MemoryStatDAO {
+public interface MemoryStatDAO extends Countable {
 
     static Key<Long> memoryTotalKey = new Key<>("total", false);
     static Key<Long> memoryFreeKey = new Key<>("free", false);
@@ -53,7 +53,7 @@
     static Key<Long> memoryCommitLimitKey = new Key<>("commit-limit", false);
 
     static final Category memoryStatCategory = new Category("memory-stats",
-            Key.TIMESTAMP, memoryTotalKey, memoryFreeKey, memoryBuffersKey,
+            Key.AGENT_ID, Key.TIMESTAMP, memoryTotalKey, memoryFreeKey, memoryBuffersKey,
             memoryCachedKey, memorySwapTotalKey, memorySwapFreeKey, memoryCommitLimitKey);
 
     public List<MemoryStat> getLatestMemoryStats(HostRef ref);
--- a/common/src/main/java/com/redhat/thermostat/common/dao/MemoryStatDAOImpl.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/common/src/main/java/com/redhat/thermostat/common/dao/MemoryStatDAOImpl.java	Wed Apr 04 11:43:38 2012 -0400
@@ -59,9 +59,14 @@
     public List<MemoryStat> getLatestMemoryStats(HostRef ref) {
         HostLatestPojoListGetter<MemoryStat> getter = getters.get(ref);
         if (getter == null) {
-            getter = new HostLatestPojoListGetter<MemoryStat>(storage, MemoryStatDAO.memoryStatCategory, converter, ref);
+            getter = new HostLatestPojoListGetter<MemoryStat>(storage, memoryStatCategory, converter, ref);
             getters.put(ref, getter);
         }
         return getter.getLatest();
     }
+
+    @Override
+    public long getCount() {
+        return storage.getCount(memoryStatCategory);
+    }
 }
--- a/common/src/main/java/com/redhat/thermostat/common/dao/MongoDAOFactory.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/common/src/main/java/com/redhat/thermostat/common/dao/MongoDAOFactory.java	Wed Apr 04 11:43:38 2012 -0400
@@ -110,14 +110,4 @@
     public VmGcStatDAO getVmGcStatDAO() {
         return new VmGcStatDAOImpl(storage);
     }
-
-    @Override
-    public HostRefDAO getHostRefDAO() {
-        return new HostRefDAOImpl(storage);
-    }
-
-    @Override
-    public VmRefDAO getVmRefDAO() {
-        return new VmRefDAOImpl(storage);
-    }
 }
--- a/common/src/main/java/com/redhat/thermostat/common/dao/NetworkInterfaceInfoDAO.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/common/src/main/java/com/redhat/thermostat/common/dao/NetworkInterfaceInfoDAO.java	Wed Apr 04 11:43:38 2012 -0400
@@ -49,7 +49,7 @@
     static Key<String> ip6AddrKey = new Key<>("ipv6addr", false);
 
     static final Category networkInfoCategory = new Category("network-info",
-            Key.TIMESTAMP, ifaceKey, ip4AddrKey, ip6AddrKey);
+            Key.AGENT_ID, Key.TIMESTAMP, ifaceKey, ip4AddrKey, ip6AddrKey);
 
     public List<NetworkInterfaceInfo> getNetworkInterfaces(HostRef ref);
 }
--- a/common/src/main/java/com/redhat/thermostat/common/dao/NetworkInterfaceInfoDAOImpl.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/common/src/main/java/com/redhat/thermostat/common/dao/NetworkInterfaceInfoDAOImpl.java	Wed Apr 04 11:43:38 2012 -0400
@@ -55,7 +55,7 @@
 
     @Override
     public List<NetworkInterfaceInfo> getNetworkInterfaces(HostRef ref) {
-        Chunk query = new Chunk(NetworkInterfaceInfoDAO.networkInfoCategory, false);
+        Chunk query = new Chunk(networkInfoCategory, false);
         query.put(Key.AGENT_ID, ref.getAgentId());
 
         Cursor cursor = storage.findAll(query);
--- a/common/src/main/java/com/redhat/thermostat/common/dao/VmClassStatDAO.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/common/src/main/java/com/redhat/thermostat/common/dao/VmClassStatDAO.java	Wed Apr 04 11:43:38 2012 -0400
@@ -47,7 +47,7 @@
     static final Key<Long> loadedClassesKey = new Key<>("loadedClasses", false);
 
     static final Category vmClassStatsCategory = new Category(
-            "vm-class-stats", Key.VM_ID, Key.TIMESTAMP, loadedClassesKey);
+            "vm-class-stats", Key.AGENT_ID, Key.VM_ID, Key.TIMESTAMP, loadedClassesKey);
 
     public List<VmClassStat> getLatestClassStats(VmRef ref);
 
--- a/common/src/main/java/com/redhat/thermostat/common/dao/VmClassStatDAOImpl.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/common/src/main/java/com/redhat/thermostat/common/dao/VmClassStatDAOImpl.java	Wed Apr 04 11:43:38 2012 -0400
@@ -59,7 +59,7 @@
     public List<VmClassStat> getLatestClassStats(VmRef ref) {
         VmLatestPojoListGetter<VmClassStat> getter = getters.get(ref);
         if (getter == null) {
-            getter = new VmLatestPojoListGetter<VmClassStat>(storage, VmClassStatDAO.vmClassStatsCategory, converter, ref);
+            getter = new VmLatestPojoListGetter<VmClassStat>(storage, vmClassStatsCategory, converter, ref);
             getters.put(ref, getter);
         }
         return getter.getLatest();
--- a/common/src/main/java/com/redhat/thermostat/common/dao/VmCpuStatDAO.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/common/src/main/java/com/redhat/thermostat/common/dao/VmCpuStatDAO.java	Wed Apr 04 11:43:38 2012 -0400
@@ -47,7 +47,7 @@
     static final Key<Double> vmCpuLoadKey = new Key<>("processor-usage", false);
 
     static final Category vmCpuStatCategory = new Category("vm-cpu-stats",
-            Key.VM_ID, Key.TIMESTAMP, vmCpuLoadKey);
+            Key.AGENT_ID, Key.VM_ID, Key.TIMESTAMP, vmCpuLoadKey);
 
     public abstract List<VmCpuStat> getLatestVmCpuStats(VmRef ref);
 
--- a/common/src/main/java/com/redhat/thermostat/common/dao/VmCpuStatDAOImpl.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/common/src/main/java/com/redhat/thermostat/common/dao/VmCpuStatDAOImpl.java	Wed Apr 04 11:43:38 2012 -0400
@@ -59,7 +59,7 @@
     public List<VmCpuStat> getLatestVmCpuStats(VmRef ref) {
         VmLatestPojoListGetter<VmCpuStat> getter = getters.get(ref);
         if (getter == null) {
-            getter = new VmLatestPojoListGetter<VmCpuStat>(storage, VmGcStatDAO.vmGcStatsCategory, converter, ref);
+            getter = new VmLatestPojoListGetter<VmCpuStat>(storage, vmCpuStatCategory, converter, ref);
             getters.put(ref, getter);
         }
         return getter.getLatest();
--- a/common/src/main/java/com/redhat/thermostat/common/dao/VmGcStatConverter.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/common/src/main/java/com/redhat/thermostat/common/dao/VmGcStatConverter.java	Wed Apr 04 11:43:38 2012 -0400
@@ -44,7 +44,7 @@
 
     @Override
     public Chunk toChunk(VmGcStat vmGcStat) {
-        Chunk chunk = new Chunk(VmGcStatDAO.vmGcStatsCategory, false);
+        Chunk chunk = new Chunk(VmGcStatDAO.vmGcStatCategory, false);
 
         chunk.put(Key.VM_ID, vmGcStat.getVmId());
         chunk.put(Key.TIMESTAMP, vmGcStat.getTimeStamp());
--- a/common/src/main/java/com/redhat/thermostat/common/dao/VmGcStatDAO.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/common/src/main/java/com/redhat/thermostat/common/dao/VmGcStatDAO.java	Wed Apr 04 11:43:38 2012 -0400
@@ -49,8 +49,8 @@
     /** time in microseconds */
     static final Key<Long> wallTimeKey = new Key<>("wall-time", false);
 
-    static final Category vmGcStatsCategory = new Category("vm-gc-stats",
-            Key.VM_ID, Key.TIMESTAMP, collectorKey,
+    static final Category vmGcStatCategory = new Category("vm-gc-stats",
+            Key.AGENT_ID, Key.VM_ID, Key.TIMESTAMP, collectorKey,
             runCountKey, wallTimeKey);
 
     public List<VmGcStat> getLatestVmGcStats(VmRef ref);
--- a/common/src/main/java/com/redhat/thermostat/common/dao/VmGcStatDAOImpl.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/common/src/main/java/com/redhat/thermostat/common/dao/VmGcStatDAOImpl.java	Wed Apr 04 11:43:38 2012 -0400
@@ -59,7 +59,7 @@
     public List<VmGcStat> getLatestVmGcStats(VmRef ref) {
         VmLatestPojoListGetter<VmGcStat> getter = getters.get(ref);
         if (getter == null) {
-            getter = new VmLatestPojoListGetter<VmGcStat>(storage, VmGcStatDAO.vmGcStatsCategory, converter, ref);
+            getter = new VmLatestPojoListGetter<VmGcStat>(storage, vmGcStatCategory, converter, ref);
             getters.put(ref, getter);
         }
         return getter.getLatest();
--- a/common/src/main/java/com/redhat/thermostat/common/dao/VmInfoDAO.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/common/src/main/java/com/redhat/thermostat/common/dao/VmInfoDAO.java	Wed Apr 04 11:43:38 2012 -0400
@@ -36,6 +36,7 @@
 
 package com.redhat.thermostat.common.dao;
 
+import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 
@@ -43,7 +44,7 @@
 import com.redhat.thermostat.common.storage.Category;
 import com.redhat.thermostat.common.storage.Key;
 
-public interface VmInfoDAO {
+public interface VmInfoDAO extends Countable {
 
     static final Key<Integer> vmIdKey = new Key<>("vm-id", true);
     static final Key<Integer> vmPidKey = new Key<>("vm-pid", false);
@@ -62,11 +63,13 @@
     static final Key<Long> stopTimeKey = new Key<>("stop-time", false);
 
     static final Category vmInfoCategory = new Category("vm-info",
-            vmIdKey, vmPidKey, runtimeVersionKey, javaHomeKey,
+            Key.AGENT_ID, vmIdKey, vmPidKey, runtimeVersionKey, javaHomeKey,
             mainClassKey, commandLineKey,
             vmArgumentsKey, vmNameKey, vmInfoKey, vmVersionKey,
             propertiesKey, environmentKey, librariesKey,
             startTimeKey, stopTimeKey);
 
     public VmInfo getVmInfo(VmRef ref);
+
+    Collection<VmRef> getVMs(HostRef host);
 }
--- a/common/src/main/java/com/redhat/thermostat/common/dao/VmInfoDAOImpl.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/common/src/main/java/com/redhat/thermostat/common/dao/VmInfoDAOImpl.java	Wed Apr 04 11:43:38 2012 -0400
@@ -36,8 +36,13 @@
 
 package com.redhat.thermostat.common.dao;
 
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
 import com.redhat.thermostat.common.model.VmInfo;
 import com.redhat.thermostat.common.storage.Chunk;
+import com.redhat.thermostat.common.storage.Cursor;
 import com.redhat.thermostat.common.storage.Key;
 import com.redhat.thermostat.common.storage.Storage;
 
@@ -53,11 +58,48 @@
 
     @Override
     public VmInfo getVmInfo(VmRef ref) {
-        Chunk query = new Chunk(VmInfoDAO.vmInfoCategory, false);
+        Chunk query = new Chunk(vmInfoCategory, false);
         query.put(Key.AGENT_ID, ref.getAgent().getAgentId());
-        query.put(VmInfoDAO.vmIdKey, ref.getId());
+        query.put(vmIdKey, ref.getId());
         Chunk result = storage.find(query);
         return converter.fromChunk(result);
     }
 
+    @Override
+    public Collection<VmRef> getVMs(HostRef host) {
+
+        Chunk query = buildQuery(host);
+        Cursor cursor = storage.findAll(query);
+        return buildVMsFromQuery(cursor, host);
+    }
+
+    private Chunk buildQuery(HostRef host) {
+        Chunk query = new Chunk(vmInfoCategory, false);
+        query.put(Key.AGENT_ID, host.getAgentId());
+        return query;
+    }
+
+    private Collection<VmRef> buildVMsFromQuery(Cursor cursor, HostRef host) {
+        List<VmRef> vmRefs = new ArrayList<VmRef>();
+        while (cursor.hasNext()) {
+            Chunk vmChunk = cursor.next();
+            VmRef vm = buildVmRefFromChunk(vmChunk, host);
+            vmRefs.add(vm);
+        }
+
+        return vmRefs;
+    }
+
+    private VmRef buildVmRefFromChunk(Chunk vmChunk, HostRef host) {
+        Integer id = vmChunk.get(vmIdKey);
+        // TODO can we do better than the main class?
+        String mainClass = vmChunk.get(mainClassKey);
+        VmRef ref = new VmRef(host, id, mainClass);
+        return ref;
+    }
+
+    @Override
+    public long getCount() {
+        return storage.getCount(vmInfoCategory);
+    }
 }
--- a/common/src/main/java/com/redhat/thermostat/common/dao/VmMemoryStatDAO.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/common/src/main/java/com/redhat/thermostat/common/dao/VmMemoryStatDAO.java	Wed Apr 04 11:43:38 2012 -0400
@@ -73,7 +73,7 @@
     static final Key<Long> permUsedKey = new Key<>("perm.used", false);
 
     static final Category vmMemoryStatsCategory = new Category("vm-memory-stats",
-            Key.VM_ID, Key.TIMESTAMP,
+            Key.AGENT_ID, Key.VM_ID, Key.TIMESTAMP,
             edenGenKey, edenCollectorKey,
             edenCapacityKey, edenMaxCapacityKey,edenUsedKey,
             s0GenKey, s0CollectorKey, s0CapacityKey,
--- a/common/src/main/java/com/redhat/thermostat/common/dao/VmMemoryStatDAOImpl.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/common/src/main/java/com/redhat/thermostat/common/dao/VmMemoryStatDAOImpl.java	Wed Apr 04 11:43:38 2012 -0400
@@ -52,7 +52,7 @@
 
     @Override
     public VmMemoryStat getLatestMemoryStat(VmRef ref) {
-        Chunk query = new Chunk(VmMemoryStatDAO.vmMemoryStatsCategory, false);
+        Chunk query = new Chunk(vmMemoryStatsCategory, false);
         query.put(Key.AGENT_ID, ref.getAgent().getAgentId());
         query.put(Key.VM_ID, ref.getId());
         Cursor cursor = storage.findAll(query).sort(Key.TIMESTAMP, Cursor.SortDirection.DESCENDING).limit(1);
--- a/common/src/main/java/com/redhat/thermostat/common/dao/VmRefDAO.java	Wed Apr 04 14:48:12 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.common.dao;
-
-import java.util.Collection;
-
-public interface VmRefDAO {
-
-    Collection<VmRef> getVMs(HostRef host);
-
-}
--- a/common/src/main/java/com/redhat/thermostat/common/dao/VmRefDAOImpl.java	Wed Apr 04 14:48:12 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.common.dao;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import com.redhat.thermostat.common.storage.Chunk;
-import com.redhat.thermostat.common.storage.Cursor;
-import com.redhat.thermostat.common.storage.Storage;
-
-class VmRefDAOImpl implements VmRefDAO {
-
-    private Storage storage;
-
-    VmRefDAOImpl(Storage storage) {
-        this.storage = storage;
-    }
-
-    @Override
-    public Collection<VmRef> getVMs(HostRef host) {
-
-        Chunk query = buildQuery(host);
-        Cursor cursor = storage.findAll(query);
-        return buildVMsFromQuery(cursor, host);
-    }
-
-    private Chunk buildQuery(HostRef host) {
-        Chunk query = new Chunk(VmInfoDAO.vmInfoCategory, false);
-        query.put(HostRefDAO.agentIdKey, host.getAgentId());
-        return query;
-    }
-
-    private Collection<VmRef> buildVMsFromQuery(Cursor cursor, HostRef host) {
-        List<VmRef> vmRefs = new ArrayList<VmRef>();
-        while (cursor.hasNext()) {
-            Chunk vmChunk = cursor.next();
-            VmRef vm = buildVmRefFromChunk(vmChunk, host);
-            vmRefs.add(vm);
-        }
-
-        return vmRefs;
-    }
-
-    private VmRef buildVmRefFromChunk(Chunk vmChunk, HostRef host) {
-        Integer id = vmChunk.get(VmInfoDAO.vmIdKey);
-        // TODO can we do better than the main class?
-        String mainClass = vmChunk.get(VmInfoDAO.mainClassKey);
-        VmRef ref = new VmRef(host, id, mainClass);
-        return ref;
-    }
-}
--- a/common/src/main/java/com/redhat/thermostat/common/storage/ChunkConverter.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/common/src/main/java/com/redhat/thermostat/common/storage/ChunkConverter.java	Wed Apr 04 11:43:38 2012 -0400
@@ -38,12 +38,16 @@
 
 import java.util.HashMap;
 import java.util.Map;
+import java.util.logging.Logger;
 
 import com.mongodb.BasicDBObject;
 import com.mongodb.DBObject;
+import com.redhat.thermostat.common.utils.LoggingUtils;
 
 class ChunkConverter {
 
+    private static final Logger logger = LoggingUtils.getLogger(ChunkConverter.class);
+
     DBObject chunkToDBObject(Chunk chunk) {
         BasicDBObject dbObject = new BasicDBObject();
         Map<String, DBObject> dbObjectMap = null;
@@ -101,13 +105,15 @@
 
     private void dbObjectToChunkRecurse(Chunk chunk, DBObject dbObject, Category category, String fullKey) {
         for (String dbKey : dbObject.keySet()) {
-            String newFullKey;
-            if (fullKey == null) {
-                newFullKey = dbKey;
-            } else {
-                newFullKey = fullKey + "." + dbKey;
+            if (!dbKey.equals("_id")) { // Mongo adds this to any stored document.
+                String newFullKey;
+                if (fullKey == null) {
+                    newFullKey = dbKey;
+                } else {
+                    newFullKey = fullKey + "." + dbKey;
+                }
+                dbObjectToChunkRecursively(chunk, dbObject, category, dbKey, newFullKey);
             }
-            dbObjectToChunkRecursively(chunk, dbObject, category, dbKey, newFullKey);
         }
     }
 
@@ -118,7 +124,11 @@
             dbObjectToChunkRecurse(chunk, dbObj, category, fullKey);
         } else {
             Key key = category.getKey(fullKey);
-            chunk.put(key, value);
+            if (key != null) {
+                chunk.put(key, value);
+            } else {
+                logger.warning("No key matching \"" + fullKey + "\" in category \"" + category + "\"");
+            }
         }
     }
 }
--- a/common/src/main/java/com/redhat/thermostat/common/storage/MongoStorage.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/common/src/main/java/com/redhat/thermostat/common/storage/MongoStorage.java	Wed Apr 04 11:43:38 2012 -0400
@@ -161,14 +161,16 @@
                     replaceKeyNested.append(entryParts[1], replaceKeyNested);
                 }
             } else {
-                String mongoKey = key.getName();
-                Object value = chunk.get(key);
-                if ((value == null) && isKey) {
-                    throwMissingKey(key.getName());
-                }
-                toInsert.append(mongoKey, value);
-                if (replace && isKey) {
-                    replaceKey.append(mongoKey, value);
+                if (!key.equals(Key.AGENT_ID)) {
+                    String mongoKey = key.getName();
+                    Object value = chunk.get(key);
+                    if ((value == null) && isKey) {
+                        throwMissingKey(key.getName());
+                    }
+                    toInsert.append(mongoKey, value);
+                    if (replace && isKey) {
+                        replaceKey.append(mongoKey, value);
+                    }
                 }
             }
         }
@@ -245,7 +247,7 @@
 
     private DBCollection getCachedCollection(String collName) {
         DBCollection coll = collectionCache.get(collName);
-        if (coll == null) {
+        if (coll == null && db.collectionExists(collName)) {
             coll = db.getCollection(collName);
             if (coll != null) {
                 collectionCache.put(collName, coll);
@@ -294,6 +296,11 @@
 
     @Override
     public ConnectionKey createConnectionKey(Category category) {
+        // TODO: There is probably some better place to do this, perhaps related to the inner class
+        // idea mentioned below.
+        if (!db.collectionExists(category.getName())) {
+            db.createCollection(category.getName(), new BasicDBObject("capped", false));
+        }
         // TODO: We want to return an instance of an inner class here that carries the actual connection
         // and replace the collectionCache. For now this is good enough though.
         return new ConnectionKey(){};
@@ -330,4 +337,13 @@
         DBCursor dbCursor = coll.find();
         return new MongoCursor(dbCursor, category);
     }
+
+    @Override
+    public long getCount(Category category) {
+        DBCollection coll = getCachedCollection(category.getName());
+        if (coll != null) {
+            return coll.getCount();
+        }
+        return 0L;
+    }
 }
--- a/common/src/main/java/com/redhat/thermostat/common/storage/Storage.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/common/src/main/java/com/redhat/thermostat/common/storage/Storage.java	Wed Apr 04 11:43:38 2012 -0400
@@ -84,4 +84,6 @@
     public abstract Chunk find(Chunk query);
 
     public abstract Cursor findAllFromCategory(Category category);
+
+    public abstract long getCount(Category category);
 }
--- a/common/src/test/java/com/redhat/thermostat/common/dao/CpuStatDAOTest.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/common/src/test/java/com/redhat/thermostat/common/dao/CpuStatDAOTest.java	Wed Apr 04 11:43:38 2012 -0400
@@ -52,6 +52,7 @@
 import org.mockito.ArgumentCaptor;
 
 import com.redhat.thermostat.common.model.CpuStat;
+import com.redhat.thermostat.common.storage.Category;
 import com.redhat.thermostat.common.storage.Chunk;
 import com.redhat.thermostat.common.storage.Cursor;
 import com.redhat.thermostat.common.storage.Key;
@@ -67,28 +68,28 @@
         assertTrue(keys.contains(new Key<Double>("5load", false)));
         assertTrue(keys.contains(new Key<Double>("10load", false)));
         assertTrue(keys.contains(new Key<Double>("15load", false)));
-        assertEquals(4, keys.size());
+        assertEquals(5, keys.size());
     }
 
     @Test
     public void testGetLatestCpuStats() {
+
+        Cursor cursor = mock(Cursor.class);
+        Storage storage = mock(Storage.class);
+        HostRef hostRef = mock(HostRef.class);
+        CpuStatDAO dao = new CpuStatDAOImpl(storage);
+
         Chunk chunk = new Chunk(CpuStatDAO.cpuStatCategory, false);
         chunk.put(Key.TIMESTAMP, 1234L);
         chunk.put(CpuStatDAO.cpu5LoadKey, 5.0);
         chunk.put(CpuStatDAO.cpu10LoadKey, 10.0);
         chunk.put(CpuStatDAO.cpu15LoadKey, 15.0);
 
-        Cursor cursor = mock(Cursor.class);
         when(cursor.hasNext()).thenReturn(true).thenReturn(false);
         when(cursor.next()).thenReturn(chunk);
-
-        Storage storage = mock(Storage.class);
         when(storage.findAll(any(Chunk.class))).thenReturn(cursor);
-
-        HostRef hostRef = mock(HostRef.class);
         when(hostRef.getAgentId()).thenReturn("system");
 
-        CpuStatDAO dao = new CpuStatDAOImpl(storage);
         List<CpuStat> cpuStats = dao.getLatestCpuStats(hostRef);
 
         ArgumentCaptor<Chunk> arg = ArgumentCaptor.forClass(Chunk.class);
@@ -105,29 +106,38 @@
 
     @Test
     public void testGetLatestCpuStatsTwice() {
+
+        Cursor cursor = mock(Cursor.class);
+        Storage storage = mock(Storage.class);
+        HostRef hostRef = mock(HostRef.class);
+
+        CpuStatDAO dao = new CpuStatDAOImpl(storage);
+
         Chunk chunk = new Chunk(CpuStatDAO.cpuStatCategory, false);
         chunk.put(Key.TIMESTAMP, 1234L);
         chunk.put(CpuStatDAO.cpu5LoadKey, 5.0);
         chunk.put(CpuStatDAO.cpu10LoadKey, 10.0);
         chunk.put(CpuStatDAO.cpu15LoadKey, 15.0);
 
-        Cursor cursor = mock(Cursor.class);
         when(cursor.hasNext()).thenReturn(true).thenReturn(false);
         when(cursor.next()).thenReturn(chunk);
-
-        Storage storage = mock(Storage.class);
         when(storage.findAll(any(Chunk.class))).thenReturn(cursor);
-
-        HostRef hostRef = mock(HostRef.class);
         when(hostRef.getAgentId()).thenReturn("system");
 
-        CpuStatDAO dao = new CpuStatDAOImpl(storage);
         dao.getLatestCpuStats(hostRef);
         dao.getLatestCpuStats(hostRef);
 
         ArgumentCaptor<Chunk> arg = ArgumentCaptor.forClass(Chunk.class);
         verify(storage, times(2)).findAll(arg.capture());
-        assertEquals("this.timestamp > 1234", arg.getValue().get(new Key<String>("$where", false)));
+        assertEquals("this.timestamp > 1234", arg.getValue().get(Key.WHERE));
     }
 
+    @Test
+    public void testGetCount() {
+        Storage storage = mock(Storage.class);
+        when(storage.getCount(any(Category.class))).thenReturn(5L);
+        CpuStatDAO dao = new CpuStatDAOImpl(storage);
+        Long count = dao.getCount();
+        assertEquals((Long) 5L, count);
+    }
 }
--- a/common/src/test/java/com/redhat/thermostat/common/dao/HostInfoDAOTest.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/common/src/test/java/com/redhat/thermostat/common/dao/HostInfoDAOTest.java	Wed Apr 04 11:43:38 2012 -0400
@@ -36,7 +36,9 @@
 
 package com.redhat.thermostat.common.dao;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
 import java.util.Collection;
 
@@ -47,7 +49,9 @@
 import static org.mockito.Mockito.when;
 
 import com.redhat.thermostat.common.model.HostInfo;
+import com.redhat.thermostat.common.storage.Category;
 import com.redhat.thermostat.common.storage.Chunk;
+import com.redhat.thermostat.common.storage.Cursor;
 import com.redhat.thermostat.common.storage.Key;
 import com.redhat.thermostat.common.storage.Storage;
 
@@ -63,7 +67,7 @@
         assertTrue(keys.contains(new Key<String>("cpu_model", false)));
         assertTrue(keys.contains(new Key<Integer>("cpu_num", false)));
         assertTrue(keys.contains(new Key<Long>("memory_total", false)));
-        assertEquals(6, keys.size());
+        assertEquals(7, keys.size());
     }
 
     @Test
@@ -95,4 +99,77 @@
         assertEquals(CPU_NUM, info.getCpuCount());
         assertEquals(MEMORY_TOTAL, info.getTotalMemory());
     }
+
+    @Test
+    public void testGetHostsSingleHost() {
+
+        Storage storage = setupStorageForSingleHost();
+
+        HostInfoDAO hostsDAO = new HostInfoDAOImpl(storage);
+        Collection<HostRef> hosts = hostsDAO.getHosts();
+
+        assertEquals(1, hosts.size());
+        assertTrue(hosts.contains(new HostRef("123", "fluffhost1")));
+    }
+
+    private Storage setupStorageForSingleHost() {
+
+        Chunk hostConfig = new Chunk(HostInfoDAO.hostInfoCategory, false);
+        hostConfig.put(HostInfoDAO.hostNameKey, "fluffhost1");
+        hostConfig.put(Key.AGENT_ID, "123");
+
+        Cursor cursor = mock(Cursor.class);
+        when(cursor.hasNext()).thenReturn(true).thenReturn(false);
+        when(cursor.next()).thenReturn(hostConfig);
+
+        Storage storage = mock(Storage.class);
+        when(storage.findAllFromCategory(HostInfoDAO.hostInfoCategory)).thenReturn(cursor);
+
+        return storage;
+    }
+
+    @Test
+    public void testGetHosts3Hosts() {
+
+        Storage storage = setupStorageFor3Hosts();
+
+        HostInfoDAO hostsDAO = new HostInfoDAOImpl(storage);
+        Collection<HostRef> hosts = hostsDAO.getHosts();
+
+        assertEquals(3, hosts.size());
+        assertTrue(hosts.contains(new HostRef("123", "fluffhost1")));
+        assertTrue(hosts.contains(new HostRef("456", "fluffhost2")));
+        assertTrue(hosts.contains(new HostRef("789", "fluffhost3")));
+    }
+
+    private Storage setupStorageFor3Hosts() {
+
+        Chunk hostConfig1 = new Chunk(HostInfoDAO.hostInfoCategory, false);
+        hostConfig1.put(HostInfoDAO.hostNameKey, "fluffhost1");
+        hostConfig1.put(Key.AGENT_ID, "123");
+        Chunk hostConfig2 = new Chunk(HostInfoDAO.hostInfoCategory, false);
+        hostConfig2.put(HostInfoDAO.hostNameKey, "fluffhost2");
+        hostConfig2.put(Key.AGENT_ID, "456");
+        Chunk hostConfig3 = new Chunk(HostInfoDAO.hostInfoCategory, false);
+        hostConfig3.put(HostInfoDAO.hostNameKey, "fluffhost3");
+        hostConfig3.put(Key.AGENT_ID, "789");
+
+        Cursor cursor = mock(Cursor.class);
+        when(cursor.hasNext()).thenReturn(true).thenReturn(true).thenReturn(true).thenReturn(false);
+        when(cursor.next()).thenReturn(hostConfig1).thenReturn(hostConfig2).thenReturn(hostConfig3);
+
+        Storage storage = mock(Storage.class);
+        when(storage.findAllFromCategory(HostInfoDAO.hostInfoCategory)).thenReturn(cursor);
+
+        return storage;
+    }
+
+    @Test
+    public void testGetCount() {
+        Storage storage = mock(Storage.class);
+        when(storage.getCount(any(Category.class))).thenReturn(5L);
+        HostInfoDAO dao = new HostInfoDAOImpl(storage);
+        Long count = dao.getCount();
+        assertEquals((Long) 5L, count);
+    }
 }
--- a/common/src/test/java/com/redhat/thermostat/common/dao/HostRefDAOTest.java	Wed Apr 04 14:48:12 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,149 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.common.dao;
-
-import static org.junit.Assert.*;
-
-import java.util.Collection;
-
-import org.junit.Test;
-
-import com.redhat.thermostat.common.storage.Chunk;
-import com.redhat.thermostat.common.storage.Cursor;
-import com.redhat.thermostat.common.storage.Key;
-import com.redhat.thermostat.common.storage.Storage;
-import static org.mockito.Mockito.*;
-
-public class HostRefDAOTest {
-
-    @Test
-    public void testKeys() {
-        assertEquals(new Key<String>("agent-id", false), HostRefDAO.agentIdKey);
-    }
-
-    @Test
-    public void testAgentConfigCategory() {
-        assertEquals("agent-config", HostRefDAO.agentConfigCategory.getName());
-        assertEquals(1, HostRefDAO.agentConfigCategory.getKeys().size());
-        assertTrue(HostRefDAO.agentConfigCategory.getKeys().contains(HostRefDAO.agentIdKey));
-    }
-
-    @Test
-    public void testGetHostsSingleHost() {
-
-        Storage storage = setupStorageForSingleHost();
-
-        HostRefDAO hostsVMsDAO = new HostRefDAOImpl(storage);
-        Collection<HostRef> hosts = hostsVMsDAO.getHosts();
-
-        assertEquals(1, hosts.size());
-        assertTrue(hosts.contains(new HostRef("123", "fluffhost1")));
-    }
-
-    private Storage setupStorageForSingleHost() {
-        
-        Chunk agentConfig = new Chunk(HostRefDAO.agentConfigCategory, false);
-        agentConfig.put(HostRefDAO.agentIdKey, "123");
-
-        Cursor agentsCursor = mock(Cursor.class);
-        when(agentsCursor.hasNext()).thenReturn(true).thenReturn(false);
-        when(agentsCursor.next()).thenReturn(agentConfig);
-
-        Chunk hostConfig = new Chunk(HostInfoDAO.hostInfoCategory, false);
-        hostConfig.put(HostInfoDAO.hostNameKey, "fluffhost1");
-        hostConfig.put(HostRefDAO.agentIdKey, "123");
-
-        Storage storage = mock(Storage.class);
-        when(storage.findAllFromCategory(HostRefDAO.agentConfigCategory)).thenReturn(agentsCursor);
-        Chunk hostsQuery = new Chunk(HostInfoDAO.hostInfoCategory, false);
-        hostsQuery.put(HostRefDAO.agentIdKey, "123");
-        when(storage.find(hostsQuery)).thenReturn(hostConfig);
-
-        return storage;
-    }
-
-    @Test
-    public void testGetHosts3Hosts() {
-
-        Storage storage = setupStorageFor3Hosts();
-
-        HostRefDAO hostsVMsDAO = new HostRefDAOImpl(storage);
-        Collection<HostRef> hosts = hostsVMsDAO.getHosts();
-
-        assertEquals(3, hosts.size());
-        assertTrue(hosts.contains(new HostRef("123", "fluffhost1")));
-        assertTrue(hosts.contains(new HostRef("456", "fluffhost2")));
-        assertTrue(hosts.contains(new HostRef("789", "fluffhost3")));
-    }
-
-    private Storage setupStorageFor3Hosts() {
-        Chunk agentConfig1 = new Chunk(HostRefDAO.agentConfigCategory, false);
-        agentConfig1.put(HostRefDAO.agentIdKey, "123");
-        Chunk agentConfig2 = new Chunk(HostRefDAO.agentConfigCategory, false);
-        agentConfig2.put(HostRefDAO.agentIdKey, "456");
-        Chunk agentConfig3 = new Chunk(HostRefDAO.agentConfigCategory, false);
-        agentConfig3.put(HostRefDAO.agentIdKey, "789");
-
-        Cursor agentsCursor = mock(Cursor.class);
-        when(agentsCursor.hasNext()).thenReturn(true).thenReturn(true).thenReturn(true).thenReturn(false);
-        when(agentsCursor.next()).thenReturn(agentConfig1).thenReturn(agentConfig2).thenReturn(agentConfig3);
-
-        Chunk hostConfig1 = new Chunk(HostInfoDAO.hostInfoCategory, false);
-        hostConfig1.put(HostInfoDAO.hostNameKey, "fluffhost1");
-        hostConfig1.put(HostRefDAO.agentIdKey, "123");
-        Chunk hostConfig2 = new Chunk(HostInfoDAO.hostInfoCategory, false);
-        hostConfig2.put(HostInfoDAO.hostNameKey, "fluffhost2");
-        hostConfig2.put(HostRefDAO.agentIdKey, "456");
-        Chunk hostConfig3 = new Chunk(HostInfoDAO.hostInfoCategory, false);
-        hostConfig3.put(HostInfoDAO.hostNameKey, "fluffhost3");
-        hostConfig3.put(HostRefDAO.agentIdKey, "789");
-
-        Storage storage = mock(Storage.class);
-        when(storage.findAllFromCategory(HostRefDAO.agentConfigCategory)).thenReturn(agentsCursor);
-        Chunk hostsQuery1 = new Chunk(HostInfoDAO.hostInfoCategory, false);
-        hostsQuery1.put(HostRefDAO.agentIdKey, "123");
-        when(storage.find(hostsQuery1)).thenReturn(hostConfig1);
-        Chunk hostsQuery2 = new Chunk(HostInfoDAO.hostInfoCategory, false);
-        hostsQuery2.put(HostRefDAO.agentIdKey, "456");
-        when(storage.find(hostsQuery2)).thenReturn(hostConfig2);
-        Chunk hostsQuery3 = new Chunk(HostInfoDAO.hostInfoCategory, false);
-        hostsQuery3.put(HostRefDAO.agentIdKey, "789");
-        when(storage.find(hostsQuery3)).thenReturn(hostConfig3);
-
-        return storage;
-    }
-}
--- a/common/src/test/java/com/redhat/thermostat/common/dao/MemoryStatDAOTest.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/common/src/test/java/com/redhat/thermostat/common/dao/MemoryStatDAOTest.java	Wed Apr 04 11:43:38 2012 -0400
@@ -52,6 +52,7 @@
 import org.mockito.ArgumentCaptor;
 
 import com.redhat.thermostat.common.model.MemoryStat;
+import com.redhat.thermostat.common.storage.Category;
 import com.redhat.thermostat.common.storage.Chunk;
 import com.redhat.thermostat.common.storage.Cursor;
 import com.redhat.thermostat.common.storage.Key;
@@ -70,7 +71,7 @@
         assertTrue(keys.contains(new Key<Long>("swap-total", false)));
         assertTrue(keys.contains(new Key<Long>("swap-free", false)));
         assertTrue(keys.contains(new Key<Long>("commit-limit", false)));
-        assertEquals(8, keys.size());
+        assertEquals(9, keys.size());
 
     }
 
@@ -164,4 +165,13 @@
         verify(storage, times(2)).findAll(arg.capture());
         assertEquals("this.timestamp > 1", arg.getValue().get(new Key<String>("$where", false)));
     }
+
+    @Test
+    public void testGetCount() {
+        Storage storage = mock(Storage.class);
+        when(storage.getCount(any(Category.class))).thenReturn(5L);
+        MemoryStatDAO dao = new MemoryStatDAOImpl(storage);
+        Long count = dao.getCount();
+        assertEquals((Long) 5L, count);
+    }
 }
--- a/common/src/test/java/com/redhat/thermostat/common/dao/MongoDAOFactoryTest.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/common/src/test/java/com/redhat/thermostat/common/dao/MongoDAOFactoryTest.java	Wed Apr 04 11:43:38 2012 -0400
@@ -118,16 +118,4 @@
         NetworkInterfaceInfoDAO dao = daoFactory.getNetworkInterfaceInfoDAO();
         assertNotNull(dao);
     }
-
-    @Test
-    public void testGetHostRefDAO() {
-        HostRefDAO dao = daoFactory.getHostRefDAO();
-        assertNotNull(dao);
-    }
-
-    @Test
-    public void testGetVmRefDAO() {
-        VmRefDAO dao = daoFactory.getVmRefDAO();
-        assertNotNull(dao);
-    }
 }
--- a/common/src/test/java/com/redhat/thermostat/common/dao/NetworkInterfaceInfoDAOTest.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/common/src/test/java/com/redhat/thermostat/common/dao/NetworkInterfaceInfoDAOTest.java	Wed Apr 04 11:43:38 2012 -0400
@@ -69,7 +69,7 @@
         assertTrue(keys.contains(new Key<String>("iface", true)));
         assertTrue(keys.contains(new Key<String>("ipv4addr", false)));
         assertTrue(keys.contains(new Key<String>("ipv6addr", false)));
-        assertEquals(4, keys.size());
+        assertEquals(5, keys.size());
     }
 
     @Test
--- a/common/src/test/java/com/redhat/thermostat/common/dao/VmClassStatDAOTest.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/common/src/test/java/com/redhat/thermostat/common/dao/VmClassStatDAOTest.java	Wed Apr 04 11:43:38 2012 -0400
@@ -66,7 +66,7 @@
         assertTrue(keys.contains(new Key<Integer>("vm-id", false)));
         assertTrue(keys.contains(new Key<Long>("timestamp", false)));
         assertTrue(keys.contains(new Key<Long>("loadedClasses", false)));
-        assertEquals(3, keys.size());
+        assertEquals(4, keys.size());
 
     }
 
--- a/common/src/test/java/com/redhat/thermostat/common/dao/VmCpuStatDAOTest.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/common/src/test/java/com/redhat/thermostat/common/dao/VmCpuStatDAOTest.java	Wed Apr 04 11:43:38 2012 -0400
@@ -66,7 +66,7 @@
         assertTrue(keys.contains(new Key<Long>("timestamp", false)));
         assertTrue(keys.contains(new Key<Integer>("vm-id", false)));
         assertTrue(keys.contains(new Key<Integer>("processor-usage", false)));
-        assertEquals(3, keys.size());
+        assertEquals(4, keys.size());
     }
 
     @Test
--- a/common/src/test/java/com/redhat/thermostat/common/dao/VmGcStatConverterTest.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/common/src/test/java/com/redhat/thermostat/common/dao/VmGcStatConverterTest.java	Wed Apr 04 11:43:38 2012 -0400
@@ -74,7 +74,7 @@
         final Long RUN_COUNT = 10L;
         final Long WALL_TIME = 9L;
 
-        Chunk chunk = new Chunk(VmGcStatDAO.vmGcStatsCategory, false);
+        Chunk chunk = new Chunk(VmGcStatDAO.vmGcStatCategory, false);
         chunk.put(Key.TIMESTAMP, TIMESTAMP);
         chunk.put(Key.VM_ID, VM_ID);
         chunk.put(VmGcStatDAO.collectorKey, COLLECTOR);
--- a/common/src/test/java/com/redhat/thermostat/common/dao/VmGcStatDAOTest.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/common/src/test/java/com/redhat/thermostat/common/dao/VmGcStatDAOTest.java	Wed Apr 04 11:43:38 2012 -0400
@@ -62,14 +62,14 @@
 
     @Test
     public void testCategory() {
-        assertEquals("vm-gc-stats", VmGcStatDAO.vmGcStatsCategory.getName());
-        Collection<Key<?>> keys = VmGcStatDAO.vmGcStatsCategory.getKeys();
+        assertEquals("vm-gc-stats", VmGcStatDAO.vmGcStatCategory.getName());
+        Collection<Key<?>> keys = VmGcStatDAO.vmGcStatCategory.getKeys();
         assertTrue(keys.contains(new Key<Integer>("vm-id", false)));
         assertTrue(keys.contains(new Key<Long>("timestamp", false)));
         assertTrue(keys.contains(new Key<String>("collector", false)));
         assertTrue(keys.contains(new Key<Long>("runtime-count", false)));
         assertTrue(keys.contains(new Key<Long>("wall-time", false)));
-        assertEquals(5, keys.size());
+        assertEquals(6, keys.size());
     }
 
     @Test
@@ -81,7 +81,7 @@
         final Long RUN_COUNT = 10L;
         final Long WALL_TIME = 9L;
 
-        Chunk chunk = new Chunk(VmGcStatDAO.vmGcStatsCategory, false);
+        Chunk chunk = new Chunk(VmGcStatDAO.vmGcStatCategory, false);
         chunk.put(Key.TIMESTAMP, TIMESTAMP);
         chunk.put(Key.VM_ID, VM_ID);
         chunk.put(VmGcStatDAO.collectorKey, COLLECTOR);
@@ -128,7 +128,7 @@
         final Long RUN_COUNT = 10L;
         final Long WALL_TIME = 9L;
 
-        Chunk chunk = new Chunk(VmGcStatDAO.vmGcStatsCategory, false);
+        Chunk chunk = new Chunk(VmGcStatDAO.vmGcStatCategory, false);
         chunk.put(Key.TIMESTAMP, TIMESTAMP);
         chunk.put(Key.VM_ID, VM_ID);
         chunk.put(VmGcStatDAO.collectorKey, COLLECTOR);
--- a/common/src/test/java/com/redhat/thermostat/common/dao/VmInfoDAOTest.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/common/src/test/java/com/redhat/thermostat/common/dao/VmInfoDAOTest.java	Wed Apr 04 11:43:38 2012 -0400
@@ -49,11 +49,14 @@
 import java.util.List;
 import java.util.Map;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
 import com.redhat.thermostat.common.model.VmInfo;
+import com.redhat.thermostat.common.storage.Category;
 import com.redhat.thermostat.common.storage.Chunk;
+import com.redhat.thermostat.common.storage.Cursor;
 import com.redhat.thermostat.common.storage.Key;
 import com.redhat.thermostat.common.storage.Storage;
 
@@ -73,6 +76,7 @@
     private Map<String, String> props;
     private Map<String, String> env;
     private List<String> libs;
+    private VmInfoDAO dao;
 
     @Before
     public void setUp() {
@@ -90,6 +94,13 @@
         props = new HashMap<>();
         env = new HashMap<>();
         libs = new ArrayList<>();
+        Storage storage = setupStorageForSingleVM();
+        dao = new VmInfoDAOImpl(storage);
+    }
+
+    @After
+    public void tearDown() {
+        dao = null;
     }
 
     @Test
@@ -111,7 +122,7 @@
         assertTrue(keys.contains(new Key<List<String>>("libraries", false)));
         assertTrue(keys.contains(new Key<Long>("start-time", false)));
         assertTrue(keys.contains(new Key<Long>("stop-time", false)));
-        assertEquals(15, keys.size());
+        assertEquals(16, keys.size());
     }
 
     @Test
@@ -162,4 +173,67 @@
 
         // FIXME test environment, properties and loaded native libraries later
     }
+
+    private Storage setupStorageForSingleVM() {
+        Chunk query1 = new Chunk(VmInfoDAO.vmInfoCategory, false);
+        query1.put(Key.AGENT_ID, "123");
+
+        Chunk query2 = new Chunk(VmInfoDAO.vmInfoCategory, false);
+        query2.put(Key.AGENT_ID, "456");
+
+        Chunk vm1 = new Chunk(VmInfoDAO.vmInfoCategory, false);
+        vm1.put(VmInfoDAO.vmIdKey, 123);
+        vm1.put(VmInfoDAO.mainClassKey, "mainClass1");
+
+        Chunk vm2 = new Chunk(VmInfoDAO.vmInfoCategory, false);
+        vm2.put(VmInfoDAO.vmIdKey, 456);
+        vm2.put(VmInfoDAO.mainClassKey, "mainClass2");
+
+        Cursor singleVMCursor = mock(Cursor.class);
+        when(singleVMCursor.hasNext()).thenReturn(true).thenReturn(false);
+        when(singleVMCursor.next()).thenReturn(vm1);
+
+        Cursor multiVMsCursor = mock(Cursor.class);
+        when(multiVMsCursor.hasNext()).thenReturn(true).thenReturn(true).thenReturn(false);
+        when(multiVMsCursor.next()).thenReturn(vm1).thenReturn(vm2);
+
+        Storage storage = mock(Storage.class);
+        when(storage.findAll(query1)).thenReturn(singleVMCursor);
+        when(storage.findAll(query2)).thenReturn(multiVMsCursor);
+        return storage;
+    }
+
+    @Test
+    public void testSingleVM() {
+        HostRef host = new HostRef("123", "fluffhost");
+
+        Collection<VmRef> vms = dao.getVMs(host);
+
+        assertCollection(vms, new VmRef(host, 123, "mainClass1"));
+    }
+
+    @Test
+    public void testMultiVMs() {
+        HostRef host = new HostRef("456", "fluffhost");
+
+        Collection<VmRef> vms = dao.getVMs(host);
+
+        assertCollection(vms, new VmRef(host, 123, "mainClass1"), new VmRef(host, 456, "mainClass2"));
+    }
+
+    private void assertCollection(Collection<VmRef> vms, VmRef... expectedVMs) {
+        assertEquals(expectedVMs.length, vms.size());
+        for (VmRef expectedVM : expectedVMs) {
+            assertTrue(vms.contains(expectedVM));
+        }
+    }
+
+    @Test
+    public void testGetCount() {
+        Storage storage = mock(Storage.class);
+        when(storage.getCount(any(Category.class))).thenReturn(5L);
+        VmInfoDAO dao = new VmInfoDAOImpl(storage);
+        Long count = dao.getCount();
+        assertEquals((Long) 5L, count);
+    }
 }
--- a/common/src/test/java/com/redhat/thermostat/common/dao/VmMemoryStatDAOTest.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/common/src/test/java/com/redhat/thermostat/common/dao/VmMemoryStatDAOTest.java	Wed Apr 04 11:43:38 2012 -0400
@@ -91,7 +91,7 @@
         assertTrue(keys.contains(new Key<Long>("perm.capacity", false)));
         assertTrue(keys.contains(new Key<Long>("perm.max-capacity", false)));
         assertTrue(keys.contains(new Key<Long>("perm.used", false)));
-        assertEquals(27, keys.size());
+        assertEquals(28, keys.size());
     }
 
     @Test
--- a/common/src/test/java/com/redhat/thermostat/common/dao/VmRefDAOTest.java	Wed Apr 04 14:48:12 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,123 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.common.dao;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.util.Collection;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import com.redhat.thermostat.common.storage.Chunk;
-import com.redhat.thermostat.common.storage.Cursor;
-import com.redhat.thermostat.common.storage.Storage;
-
-public class VmRefDAOTest {
-
-    private VmRefDAO dao;
-
-    @Before
-    public void setUp() {
-        Storage storage = setupStorageForSingleVM();
-        dao = new VmRefDAOImpl(storage);
-    }
-
-    @After
-    public void tearDown() {
-        dao = null;
-    }
-
-    private Storage setupStorageForSingleVM() {
-        Chunk query1 = new Chunk(VmInfoDAO.vmInfoCategory, false);
-        query1.put(HostRefDAO.agentIdKey, "123");
-
-        Chunk query2 = new Chunk(VmInfoDAO.vmInfoCategory, false);
-        query2.put(HostRefDAO.agentIdKey, "456");
-
-        Chunk vm1 = new Chunk(VmInfoDAO.vmInfoCategory, false);
-        vm1.put(VmInfoDAO.vmIdKey, 123);
-        vm1.put(VmInfoDAO.mainClassKey, "mainClass1");
-
-        Chunk vm2 = new Chunk(VmInfoDAO.vmInfoCategory, false);
-        vm2.put(VmInfoDAO.vmIdKey, 456);
-        vm2.put(VmInfoDAO.mainClassKey, "mainClass2");
-
-        Cursor singleVMCursor = mock(Cursor.class);
-        when(singleVMCursor.hasNext()).thenReturn(true).thenReturn(false);
-        when(singleVMCursor.next()).thenReturn(vm1);
-
-        Cursor multiVMsCursor = mock(Cursor.class);
-        when(multiVMsCursor.hasNext()).thenReturn(true).thenReturn(true).thenReturn(false);
-        when(multiVMsCursor.next()).thenReturn(vm1).thenReturn(vm2);
-
-        Storage storage = mock(Storage.class);
-        when(storage.findAll(query1)).thenReturn(singleVMCursor);
-        when(storage.findAll(query2)).thenReturn(multiVMsCursor);
-        return storage;
-    }
-
-    @Test
-    public void testSingleVM() {
-        HostRef host = new HostRef("123", "fluffhost");
-
-        Collection<VmRef> vms = dao.getVMs(host);
-
-        assertCollection(vms, new VmRef(host, 123, "mainClass1"));
-    }
-
-    @Test
-    public void testMultiVMs() {
-        HostRef host = new HostRef("456", "fluffhost");
-
-        Collection<VmRef> vms = dao.getVMs(host);
-
-        assertCollection(vms, new VmRef(host, 123, "mainClass1"), new VmRef(host, 456, "mainClass2"));
-    }
-
-    private void assertCollection(Collection<VmRef> vms, VmRef... expectedVMs) {
-        assertEquals(expectedVMs.length, vms.size());
-        for (VmRef expectedVM : expectedVMs) {
-            assertTrue(vms.contains(expectedVM));
-        }
-    }
-
-}
--- a/common/src/test/java/com/redhat/thermostat/common/storage/MongoStorageTest.java	Wed Apr 04 14:48:12 2012 +0200
+++ b/common/src/test/java/com/redhat/thermostat/common/storage/MongoStorageTest.java	Wed Apr 04 11:43:38 2012 -0400
@@ -43,6 +43,7 @@
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -57,12 +58,13 @@
 import org.powermock.modules.junit4.PowerMockRunner;
 
 import com.mongodb.BasicDBObject;
+import com.mongodb.DB;
 import com.mongodb.DBCollection;
 import com.mongodb.DBCursor;
 import com.mongodb.DBObject;
 
 @RunWith(PowerMockRunner.class)
-@PrepareForTest(DBCollection.class)
+@PrepareForTest({DBCollection.class, DB.class})
 public class MongoStorageTest {
 
     private static final Key<String> key1 = new Key<>("key1", false);
@@ -71,15 +73,19 @@
     private static final Key<String> key4 = new Key<>("key4", false);
     private static final Key<String> key5 = new Key<>("key5", false);
     private static final Category testCategory = new Category("MongoStorageTest", key1, key2, key3, key4, key5);
+    private static final Category emptyTestCategory = new Category("MongoEmptyCategory");
 
     private Chunk multiKeyQuery;
 
     private MongoStorage storage;
-    private DBCollection testCollection;
+    private DB db;
+    private DBCollection testCollection, emptyTestCollection;
 
     @Before
     public void setUp() {
         storage = new MongoStorage(null);
+        db = PowerMockito.mock(DB.class);
+        storage.connect(db);
 
         BasicDBObject value1 = new BasicDBObject();
         value1.put("key1", "test1");
@@ -103,7 +109,13 @@
         when(testCollection.find(any(DBObject.class))).thenReturn(cursor);
         when(testCollection.find()).thenReturn(cursor);
         when(testCollection.findOne(any(DBObject.class))).thenReturn(value1);
+        when(testCollection.getCount()).thenReturn(2L);
         storage.mapCategoryToDBCollection(testCategory, testCollection);
+        emptyTestCollection = PowerMockito.mock(DBCollection.class);
+        when(emptyTestCollection.getCount()).thenReturn(0L);
+        storage.mapCategoryToDBCollection(emptyTestCategory, emptyTestCollection);
+        when(db.collectionExists(anyString())).thenReturn(false);
+        when(db.createCollection(anyString(), any(DBObject.class))).thenReturn(testCollection);
     }
 
     @After
@@ -116,6 +128,7 @@
     @Test
     public void testCreateConnectionKey() {
         MongoStorage mongoStorage = new MongoStorage(null);
+        mongoStorage.connect(db);
         Category category = new Category("testCreateConnectionKey");
         ConnectionKey connKey = mongoStorage.createConnectionKey(category);
         assertNotNull(connKey);
@@ -248,6 +261,24 @@
         verifyDefaultCursor(cursor);
     }
 
+    @Test
+    public void verifyGetCount() {
+        long count = storage.getCount(testCategory);
+        assertEquals(2, count);
+    }
+
+    @Test
+    public void verifyGetCountForEmptyCategory() {
+        long count = storage.getCount(emptyTestCategory);
+        assertEquals(0, count);
+    }
+
+    @Test
+    public void verifyGetCountForNonexistentCategory() {
+        long count = storage.getCount(new Category("NonExistent"));
+        assertEquals(0, count);
+    }
+
     private void verifyDefaultCursor(Cursor cursor) {
         assertTrue(cursor.hasNext());
         Chunk chunk1 = cursor.next();