changeset 219:96b8fc1109af

DAO the agent reviewed-by: neugens review-thread: http://icedtea.classpath.org/pipermail/thermostat/2012-April/000759.html
author Jon VanAlten <jon.vanalten@redhat.com>
date Thu, 12 Apr 2012 10:38:24 -0400
parents 6fb6e9890e67
children 22d3c37b94a0
files agent/src/main/java/com/redhat/thermostat/agent/Agent.java agent/src/main/java/com/redhat/thermostat/agent/AgentApplication.java agent/src/main/java/com/redhat/thermostat/backend/Backend.java agent/src/main/java/com/redhat/thermostat/backend/BackendRegistry.java agent/src/main/java/com/redhat/thermostat/backend/sample/SampleBackend.java agent/src/main/java/com/redhat/thermostat/backend/system/JvmStatHostListener.java agent/src/main/java/com/redhat/thermostat/backend/system/JvmStatVmClassListener.java agent/src/main/java/com/redhat/thermostat/backend/system/JvmStatVmListener.java agent/src/main/java/com/redhat/thermostat/backend/system/SystemBackend.java agent/src/test/java/com/redhat/thermostat/agent/AgentTest.java agent/src/test/java/com/redhat/thermostat/backend/BackendRegistryTest.java agent/src/test/java/com/redhat/thermostat/backend/system/JvmStatHostListenerTest.java agent/src/test/java/com/redhat/thermostat/backend/system/JvmStatVmClassListenerTest.java agent/src/test/java/com/redhat/thermostat/backend/system/SystemBackendTest.java common/src/main/java/com/redhat/thermostat/common/dao/CpuStatDAOImpl.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/MemoryStatDAO.java common/src/main/java/com/redhat/thermostat/common/dao/MemoryStatDAOImpl.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/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/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/MemoryStatDAOTest.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/VmGcStatDAOTest.java common/src/test/java/com/redhat/thermostat/common/dao/VmInfoDAOTest.java common/src/test/java/com/redhat/thermostat/common/dao/VmMemoryStatDAOTest.java
diffstat 40 files changed, 563 insertions(+), 171 deletions(-) [+]
line wrap: on
line diff
--- a/agent/src/main/java/com/redhat/thermostat/agent/Agent.java	Thu Apr 12 10:37:36 2012 -0400
+++ b/agent/src/main/java/com/redhat/thermostat/agent/Agent.java	Thu Apr 12 10:38:24 2012 -0400
@@ -44,6 +44,7 @@
 import com.redhat.thermostat.backend.Backend;
 import com.redhat.thermostat.backend.BackendRegistry;
 import com.redhat.thermostat.common.LaunchException;
+import com.redhat.thermostat.common.dao.DAOFactory;
 import com.redhat.thermostat.common.storage.AgentInformation;
 import com.redhat.thermostat.common.storage.BackendInformation;
 import com.redhat.thermostat.common.storage.Storage;
@@ -63,15 +64,16 @@
     private Storage storage;
     private Thread configWatcherThread = null;
 
-    public Agent(BackendRegistry backendRegistry, AgentStartupConfiguration config, Storage storage) {
-        this(backendRegistry, UUID.randomUUID(), config, storage);
+    public Agent(BackendRegistry backendRegistry, AgentStartupConfiguration config, DAOFactory daos) {
+        this(backendRegistry, UUID.randomUUID(), config, daos);
     }
 
-    public Agent(BackendRegistry registry, UUID agentId, AgentStartupConfiguration config, Storage storage) {
+    public Agent(BackendRegistry registry, UUID agentId, AgentStartupConfiguration config, DAOFactory daos) {
         this.id = agentId;
         this.backendRegistry = registry;
         this.config = config;
-        this.storage = storage;
+        this.storage = daos.getStorage();
+        this.storage.setAgentId(agentId);
     }
 
     private void startBackends() throws LaunchException {
--- a/agent/src/main/java/com/redhat/thermostat/agent/AgentApplication.java	Thu Apr 12 10:37:36 2012 -0400
+++ b/agent/src/main/java/com/redhat/thermostat/agent/AgentApplication.java	Thu Apr 12 10:38:24 2012 -0400
@@ -60,7 +60,6 @@
 import com.redhat.thermostat.common.storage.Connection;
 import com.redhat.thermostat.common.storage.StorageProvider;
 import com.redhat.thermostat.common.storage.MongoStorageProvider;
-import com.redhat.thermostat.common.storage.Storage;
 import com.redhat.thermostat.common.storage.Connection.ConnectionListener;
 import com.redhat.thermostat.common.storage.Connection.ConnectionStatus;
 import com.redhat.thermostat.common.utils.LoggingUtils;
@@ -137,16 +136,14 @@
         logger.fine("Connecting to storage...");
 
         BackendRegistry backendRegistry = null;
-        Storage storage = daoFactory.getStorage();
         try {
-            backendRegistry = new BackendRegistry(configuration, storage);
+            backendRegistry = new BackendRegistry(configuration);
         } catch (BackendLoadException ble) {
             logger.log(Level.SEVERE, "Could not get BackendRegistry instance.", ble);
             System.exit(Constants.EXIT_BACKEND_LOAD_ERROR);
         }
 
-        Agent agent = new Agent(backendRegistry, configuration, storage);
-        storage.setAgentId(agent.getId());
+        Agent agent = new Agent(backendRegistry, configuration, daoFactory);
         try {
             logger.fine("Starting agent.");
             agent.start();
--- a/agent/src/main/java/com/redhat/thermostat/backend/Backend.java	Thu Apr 12 10:37:36 2012 -0400
+++ b/agent/src/main/java/com/redhat/thermostat/backend/Backend.java	Thu Apr 12 10:38:24 2012 -0400
@@ -42,8 +42,8 @@
 import java.util.Map.Entry;
 
 import com.redhat.thermostat.common.LaunchException;
+import com.redhat.thermostat.common.dao.DAOFactory;
 import com.redhat.thermostat.common.storage.Category;
-import com.redhat.thermostat.common.storage.Chunk;
 import com.redhat.thermostat.common.storage.Storage;
 
 /**
@@ -53,6 +53,7 @@
 public abstract class Backend {
 
     private boolean initialConfigurationComplete = false;
+    protected DAOFactory df = null;
     private Storage storage = null;
     private boolean observeNewJvm = attachToNewProcessByDefault();
 
@@ -61,7 +62,7 @@
     private String description;
     
     private BackendID id;
-    
+
     /**
      * 
      * @param configMap a map containing the settings that this backend has been configured with.
@@ -69,7 +70,7 @@
      */
     protected final void setInitialConfiguration(Map<String, String> configMap) throws BackendLoadException {
         if (initialConfigurationComplete) {
-            throw new BackendLoadException("A backend may only receive intitial configuration once.");
+            throw new BackendLoadException("A backend may only receive initial configuration once.");
         }
         for (Entry<String, String> e : configMap.entrySet()) {
             String key = e.getKey();
@@ -84,13 +85,17 @@
         initialConfigurationComplete = true;
     }
 
-    public final void setStorage(Storage storage) {
-        this.storage = storage;
+    public final void setDAOFactory(DAOFactory df) {
+        this.df = df;
+        this.storage = df.getStorage();
         for (Category cat : getCategories()) {
             storage.registerCategory(cat);
         }
+        setDAOFactoryAction();
     }
 
+    protected abstract void setDAOFactoryAction();
+
     protected abstract Collection<Category> getCategories();
 
     /**
@@ -228,14 +233,6 @@
         observeNewJvm = newValue;
     }
 
-    public void store(Chunk chunk) {
-        storage.putChunk(chunk);
-    }
-
-    public void update(Chunk chunk) {
-        storage.updateChunk(chunk);
-    }
-
     void setID(BackendID backendID) {
         this.id = backendID;
     }
--- a/agent/src/main/java/com/redhat/thermostat/backend/BackendRegistry.java	Thu Apr 12 10:37:36 2012 -0400
+++ b/agent/src/main/java/com/redhat/thermostat/backend/BackendRegistry.java	Thu Apr 12 10:38:24 2012 -0400
@@ -45,7 +45,8 @@
 import java.util.logging.Logger;
 
 import com.redhat.thermostat.agent.config.AgentStartupConfiguration;
-import com.redhat.thermostat.common.storage.Storage;
+import com.redhat.thermostat.common.appctx.ApplicationContext;
+import com.redhat.thermostat.common.dao.DAOFactory;
 import com.redhat.thermostat.common.utils.LoggingUtils;
 
 /**
@@ -58,14 +59,17 @@
 
     private final Map<String, Backend> registeredBackends;
 
-    public BackendRegistry(AgentStartupConfiguration config, Storage storage) throws BackendLoadException {
-        this(config, new BackendConfigurationLoader(), storage);
+    public BackendRegistry(AgentStartupConfiguration config) throws BackendLoadException {
+        this(config, new BackendConfigurationLoader());
     }
 
-    public BackendRegistry(AgentStartupConfiguration config, BackendConfigurationLoader backendConfigLoader, Storage storage) throws BackendLoadException {
+    public BackendRegistry(AgentStartupConfiguration config, BackendConfigurationLoader backendConfigLoader) throws BackendLoadException {
+
         registeredBackends = new HashMap<String, Backend>();
         
         List<BackendID> backends = config.getBackends();
+
+        DAOFactory df = ApplicationContext.getInstance().getDAOFactory();
         
         /*
          * Configure the dynamic/custom backends
@@ -78,11 +82,11 @@
                 Class<? extends Backend> narrowed = c.asSubclass(Backend.class);
                 Constructor<? extends Backend> backendConstructor = narrowed.getConstructor();
                 backend = backendConstructor.newInstance();
-                
+
+                backend.setDAOFactory(df);
                 backend.setID(backendID);
                 
                 backend.setInitialConfiguration(backendConfigLoader.retrieveBackendConfigs(backend.getName()));
-                backend.setStorage(storage);
             } catch (Exception e) {
                 throw new BackendLoadException("Could not instantiate configured backend class: " + backendID.getClassName(), e);
             }
--- a/agent/src/main/java/com/redhat/thermostat/backend/sample/SampleBackend.java	Thu Apr 12 10:37:36 2012 -0400
+++ b/agent/src/main/java/com/redhat/thermostat/backend/sample/SampleBackend.java	Thu Apr 12 10:38:24 2012 -0400
@@ -130,4 +130,10 @@
         return false;
     }
 
+    @Override
+    protected void setDAOFactoryAction() {
+        // TODO Auto-generated method stub
+        
+    }
+
 }
--- a/agent/src/main/java/com/redhat/thermostat/backend/system/JvmStatHostListener.java	Thu Apr 12 10:37:36 2012 -0400
+++ b/agent/src/main/java/com/redhat/thermostat/backend/system/JvmStatHostListener.java	Thu Apr 12 10:38:24 2012 -0400
@@ -56,24 +56,25 @@
 
 import com.redhat.thermostat.agent.JvmStatusListener;
 import com.redhat.thermostat.agent.JvmStatusNotifier;
-import com.redhat.thermostat.common.dao.VmInfoConverter;
+import com.redhat.thermostat.common.dao.DAOFactory;
 import com.redhat.thermostat.common.dao.VmInfoDAO;
 import com.redhat.thermostat.common.model.VmInfo;
-import com.redhat.thermostat.common.storage.Chunk;
 import com.redhat.thermostat.common.utils.LoggingUtils;
 
 public class JvmStatHostListener implements HostListener, JvmStatusNotifier {
 
     private static final Logger logger = LoggingUtils.getLogger(JvmStatHostListener.class);
 
-    private SystemBackend backend;
-
-    private Map<Integer, JvmStatVmListener> listenerMap = new HashMap<Integer, JvmStatVmListener>();
+    private boolean attachNew;
+    private final DAOFactory df;
+    private final VmInfoDAO vmInfoDAO;
 
     private Set<JvmStatusListener> statusListeners = new CopyOnWriteArraySet<JvmStatusListener>();
 
-    public void setBackend(SystemBackend backend) {
-        this.backend = backend;
+    JvmStatHostListener(DAOFactory df, boolean attachNew) {
+        this.df = df;
+        this.vmInfoDAO = df.getVmInfoDAO();
+        this.attachNew = attachNew;
     }
 
     @Override
@@ -129,17 +130,15 @@
                         extractor.getMainClass(), extractor.getCommandLine(),
                         extractor.getVmName(), extractor.getVmInfo(), extractor.getVmVersion(), extractor.getVmArguments(),
                         properties, environment, loadedNativeLibraries);
-                backend.store(new VmInfoConverter().toChunk(info));
+                vmInfoDAO.putVmInfo(info);
                 logger.finer("Sent VM_STARTED messsage");
             } catch (MonitorException me) {
                 logger.log(Level.WARNING, "error getting vm info for " + vmId, me);
             }
 
-            if (backend.getObserveNewJvm()) {
-                JvmStatVmListener listener = new JvmStatVmListener(backend, vmId);
-                listenerMap.put(vmId, listener);
-                vm.addVmListener(listener);
-                vm.addVmListener(new JvmStatVmClassListener(backend, vmId));
+            if (attachNew) {
+                vm.addVmListener(new JvmStatVmListener(df, vmId));
+                vm.addVmListener(new JvmStatVmClassListener(df, vmId));
             } else {
                 logger.log(Level.FINE, "skipping new vm " + vmId);
             }
@@ -155,22 +154,13 @@
                 new VmIdentifier(vmId.toString()));
         if (resolvedVmID != null) {
             long stopTime = System.currentTimeMillis();
-            listenerMap.remove(vmId);
             for (JvmStatusListener statusListener : statusListeners) {
                 statusListener.jvmStopped(vmId);
             }
-            backend.update(makeVmInfoUpdateStoppedChunk(vmId, stopTime));
+            vmInfoDAO.putVmStoppedTime(vmId, stopTime);
         }
     }
 
-    private Chunk makeVmInfoUpdateStoppedChunk(int vmId, long stopTimeStamp) {
-        // FIXME later
-        Chunk chunk = new Chunk(VmInfoDAO.vmInfoCategory, false);
-        chunk.put(VmInfoDAO.vmIdKey, vmId);
-        chunk.put(VmInfoDAO.stopTimeKey, stopTimeStamp);
-        return chunk;
-    }
-
     @Override
     public void addJvmStatusListener(JvmStatusListener listener) {
         statusListeners.add(listener);
--- a/agent/src/main/java/com/redhat/thermostat/backend/system/JvmStatVmClassListener.java	Thu Apr 12 10:37:36 2012 -0400
+++ b/agent/src/main/java/com/redhat/thermostat/backend/system/JvmStatVmClassListener.java	Thu Apr 12 10:38:24 2012 -0400
@@ -45,7 +45,8 @@
 import sun.jvmstat.monitor.event.VmEvent;
 import sun.jvmstat.monitor.event.VmListener;
 
-import com.redhat.thermostat.common.dao.VmClassStatConverter;
+import com.redhat.thermostat.common.dao.DAOFactory;
+import com.redhat.thermostat.common.dao.VmClassStatDAO;
 import com.redhat.thermostat.common.model.VmClassStat;
 import com.redhat.thermostat.common.utils.LoggingUtils;
 
@@ -53,11 +54,11 @@
 
     private static final Logger logger = LoggingUtils.getLogger(JvmStatVmClassListener.class);
 
-    private SystemBackend backend;
+    private VmClassStatDAO dao;
     private int vmId;
 
-    JvmStatVmClassListener(SystemBackend backend, int vmId) {
-        this.backend = backend;
+    JvmStatVmClassListener(DAOFactory df, int vmId) {
+        this.dao = df.getVmClassStatsDAO();
         this.vmId = vmId;
     }
 
@@ -79,8 +80,7 @@
             long loadedClasses = extractor.getLoadedClasses();
             long timestamp = System.currentTimeMillis();
             VmClassStat stat = new VmClassStat(vmId, timestamp, loadedClasses);
-            VmClassStatConverter dao = new VmClassStatConverter();
-            backend.store(dao.toChunk(stat));
+            dao.putVmClassStat(stat);
         } catch (MonitorException e) {
             logger.log(Level.WARNING, "error gathering class info for vm " + vmId, e);
         }
--- a/agent/src/main/java/com/redhat/thermostat/backend/system/JvmStatVmListener.java	Thu Apr 12 10:37:36 2012 -0400
+++ b/agent/src/main/java/com/redhat/thermostat/backend/system/JvmStatVmListener.java	Thu Apr 12 10:38:24 2012 -0400
@@ -47,8 +47,9 @@
 import sun.jvmstat.monitor.event.VmEvent;
 import sun.jvmstat.monitor.event.VmListener;
 
-import com.redhat.thermostat.common.dao.VmGcStatConverter;
-import com.redhat.thermostat.common.dao.VmMemoryStatConverter;
+import com.redhat.thermostat.common.dao.DAOFactory;
+import com.redhat.thermostat.common.dao.VmGcStatDAO;
+import com.redhat.thermostat.common.dao.VmMemoryStatDAO;
 import com.redhat.thermostat.common.model.VmGcStat;
 import com.redhat.thermostat.common.model.VmMemoryStat;
 import com.redhat.thermostat.common.model.VmMemoryStat.Generation;
@@ -60,10 +61,12 @@
     private static final Logger logger = LoggingUtils.getLogger(JvmStatVmListener.class);
 
     private final int vmId;
-    private final SystemBackend backend;
+    private final VmGcStatDAO gcDAO;
+    private final VmMemoryStatDAO memDAO;
 
-    public JvmStatVmListener(SystemBackend backend, int vmId) {
-        this.backend = backend;
+    public JvmStatVmListener(DAOFactory df, int vmId) {
+        gcDAO = df.getVmGcStatDAO();
+        memDAO = df.getVmMemoryStatDAO();
         this.vmId = vmId;
     }
 
@@ -97,7 +100,7 @@
                         extractor.getCollectorName(i),
                         extractor.getCollectorInvocations(i),
                         extractor.getCollectorTime(i));
-                backend.store(new VmGcStatConverter().toChunk(stat));
+                gcDAO.putVmGcStat(stat);
             }
         } catch (MonitorException e) {
             logger.log(Level.WARNING, "error gathering gc info for vm " + vmId, e);
@@ -132,7 +135,7 @@
                     s.used = extractor.getSpaceUsed(generation, space);
                 }
             }
-            backend.store(new VmMemoryStatConverter().toChunk(stat));
+            memDAO.putVmMemoryStat(stat);
         } catch (MonitorException e) {
             logger.log(Level.WARNING, "error gathering memory info for vm " + vmId, e);
         }
--- a/agent/src/main/java/com/redhat/thermostat/backend/system/SystemBackend.java	Thu Apr 12 10:37:36 2012 -0400
+++ b/agent/src/main/java/com/redhat/thermostat/backend/system/SystemBackend.java	Thu Apr 12 10:38:24 2012 -0400
@@ -57,16 +57,11 @@
 import com.redhat.thermostat.backend.Backend;
 import com.redhat.thermostat.common.Clock;
 import com.redhat.thermostat.common.SystemClock;
-import com.redhat.thermostat.common.dao.CpuStatConverter;
 import com.redhat.thermostat.common.dao.CpuStatDAO;
-import com.redhat.thermostat.common.dao.HostInfoConverter;
 import com.redhat.thermostat.common.dao.HostInfoDAO;
-import com.redhat.thermostat.common.dao.MemoryStatConverter;
 import com.redhat.thermostat.common.dao.MemoryStatDAO;
-import com.redhat.thermostat.common.dao.NetworkInterfaceInfoConverter;
 import com.redhat.thermostat.common.dao.NetworkInterfaceInfoDAO;
 import com.redhat.thermostat.common.dao.VmClassStatDAO;
-import com.redhat.thermostat.common.dao.VmCpuStatConverter;
 import com.redhat.thermostat.common.dao.VmCpuStatDAO;
 import com.redhat.thermostat.common.dao.VmGcStatDAO;
 import com.redhat.thermostat.common.dao.VmInfoDAO;
@@ -79,6 +74,12 @@
 
     private static final Logger logger = LoggingUtils.getLogger(SystemBackend.class);
 
+    private CpuStatDAO cpuStats;
+    private HostInfoDAO hostInfos;
+    private MemoryStatDAO memoryStats;
+    private VmCpuStatDAO vmCpuStats;
+    private NetworkInterfaceInfoDAO networkInterfaces;
+
     private final List<Category> categories = new ArrayList<Category>();
 
     private final Set<Integer> pidsToMonitor = new CopyOnWriteArraySet<Integer>();
@@ -89,13 +90,17 @@
 
     private HostIdentifier hostId = null;
     private MonitoredHost host = null;
-    private JvmStatHostListener hostListener = new JvmStatHostListener();
+    private JvmStatHostListener hostListener;
 
     private final VmCpuStatBuilder vmCpuBuilder;
+    private final HostInfoBuilder hostInfoBuilder;
+    private final CpuStatBuilder cpuStatBuilder;
+    private final MemoryStatBuilder memoryStatBuilder;
 
     public SystemBackend() {
+        super();
+
         // Set up categories that will later be registered.
-
         categories.add(CpuStatDAO.cpuStatCategory);
         categories.add(HostInfoDAO.hostInfoCategory);
         categories.add(MemoryStatDAO.memoryStatCategory);
@@ -110,6 +115,20 @@
         ProcessStatusInfoBuilder builder = new ProcessStatusInfoBuilder(new ProcDataSource());
         long ticksPerSecond = SysConf.getClockTicksPerSecond();
         vmCpuBuilder = new VmCpuStatBuilder(clock, ticksPerSecond, builder);
+        ProcDataSource source = new ProcDataSource();
+        hostInfoBuilder = new HostInfoBuilder(source);
+        cpuStatBuilder = new CpuStatBuilder(source);
+        memoryStatBuilder = new MemoryStatBuilder(source);
+    }
+
+    @Override
+    protected void setDAOFactoryAction() {
+        cpuStats = df.getCpuStatDAO();
+        hostInfos = df.getHostInfoDAO();
+        memoryStats = df.getMemoryStatDAO();
+        vmCpuStats = df.getVmCpuStatDAO();
+        networkInterfaces = df.getNetworkInterfaceInfoDAO();
+        hostListener = new JvmStatHostListener(df, getObserveNewJvm());
     }
 
     @Override
@@ -117,28 +136,30 @@
         if (timer != null) {
             return true;
         }
+        if (df == null) {
+            throw new IllegalStateException("Cannot activate backend without DAOFactory.");
+        }
 
         addJvmStatusListener(this);
 
         if (!getObserveNewJvm()) {
             logger.fine("not monitoring new vms");
         }
-        store(new HostInfoConverter().toChunk(new HostInfoBuilder(new ProcDataSource()).build()));
+        hostInfos.putHostInfo(hostInfoBuilder.build());
 
         timer = new Timer();
         timer.scheduleAtFixedRate(new TimerTask() {
             @Override
             public void run() {
-                ProcDataSource dataSource = new ProcDataSource();
-                store(new CpuStatConverter().toChunk(new CpuStatBuilder(dataSource).build()));
+                cpuStats.putCpuStat(cpuStatBuilder.build());
                 for (NetworkInterfaceInfo info: NetworkInfoBuilder.build()) {
-                    store(new NetworkInterfaceInfoConverter().toChunk(info));
+                    networkInterfaces.putNetworkInterfaceInfo(info);
                 }
-                store(new MemoryStatConverter().toChunk(new MemoryStatBuilder(dataSource).build()));
+                memoryStats.putMemoryStat(memoryStatBuilder.build());
 
                 for (Integer pid : pidsToMonitor) {
                     if (vmCpuBuilder.knowsAbout(pid)) {
-                        store(new VmCpuStatConverter().toChunk(vmCpuBuilder.build(pid)));
+                        vmCpuStats.putVmCpuStat(vmCpuBuilder.build(pid));
                     } else {
                         vmCpuBuilder.learnAbout(pid);
                     }
@@ -149,7 +170,6 @@
         try {
             hostId = new HostIdentifier((String) null);
             host = MonitoredHost.getMonitoredHost(hostId);
-            hostListener.setBackend(this);
             host.addHostListener(hostListener);
         } catch (MonitorException me) {
             logger.log(Level.WARNING, "problems with connecting jvmstat to local machine", me);
--- a/agent/src/test/java/com/redhat/thermostat/agent/AgentTest.java	Thu Apr 12 10:37:36 2012 -0400
+++ b/agent/src/test/java/com/redhat/thermostat/agent/AgentTest.java	Thu Apr 12 10:38:24 2012 -0400
@@ -51,6 +51,7 @@
 import com.redhat.thermostat.agent.config.AgentStartupConfiguration;
 import com.redhat.thermostat.backend.Backend;
 import com.redhat.thermostat.backend.BackendRegistry;
+import com.redhat.thermostat.common.dao.DAOFactory;
 import com.redhat.thermostat.common.storage.AgentInformation;
 import com.redhat.thermostat.common.storage.BackendInformation;
 import com.redhat.thermostat.common.storage.Storage;
@@ -64,6 +65,8 @@
         when(config.getStartTime()).thenReturn(123L);
 
         Storage storage = mock(Storage.class);
+        DAOFactory daos = mock(DAOFactory.class);
+        when(daos.getStorage()).thenReturn(storage);
 
         Backend backend = mock(Backend.class);
         when(backend.getName()).thenReturn("testname");
@@ -77,7 +80,7 @@
         when(backendRegistry.getAll()).thenReturn(backends);
 
         // Start agent.
-        Agent agent = new Agent(backendRegistry, config, storage);
+        Agent agent = new Agent(backendRegistry, config, daos);
         agent.start();
 
         // Verify that backend has been activated and storage received the agent information.
--- a/agent/src/test/java/com/redhat/thermostat/backend/BackendRegistryTest.java	Thu Apr 12 10:37:36 2012 -0400
+++ b/agent/src/test/java/com/redhat/thermostat/backend/BackendRegistryTest.java	Thu Apr 12 10:38:24 2012 -0400
@@ -53,13 +53,19 @@
 import org.junit.Test;
 
 import com.redhat.thermostat.agent.config.AgentStartupConfiguration;
+import com.redhat.thermostat.common.appctx.ApplicationContext;
 import com.redhat.thermostat.common.config.InvalidConfigurationException;
+import com.redhat.thermostat.common.dao.DAOFactory;
 import com.redhat.thermostat.common.storage.Category;
 import com.redhat.thermostat.common.storage.Storage;
 
 public class BackendRegistryTest {
 
     public static class MockBackend extends Backend {
+        public MockBackend() {
+            super();
+        }
+
         @Override
         protected Collection<Category> getCategories() {
             return Collections.emptyList();
@@ -84,23 +90,32 @@
         public boolean attachToNewProcessByDefault() {
             return false;
         }
+
+        @Override
+        protected void setDAOFactoryAction() {
+            // TODO Auto-generated method stub
+            
+        }
     }
 
     private List<BackendID> backends;
     private AgentStartupConfiguration config;
     private BackendConfigurationLoader configLoader;
-    private Storage storage;
 
     @Before
     public void setUp() throws InvalidConfigurationException {
         backends = new ArrayList<>();
 
-        storage = mock(Storage.class);
         config = mock(AgentStartupConfiguration.class);
         when(config.getBackends()).thenReturn(backends);
 
         configLoader = mock(BackendConfigurationLoader.class);
         when(configLoader.retrieveBackendConfigs(any(String.class))).thenReturn(new HashMap<String,String>());
+
+        Storage storage = mock(Storage.class);
+        DAOFactory df = mock(DAOFactory.class);
+        when(df.getStorage()).thenReturn(storage);
+        ApplicationContext.getInstance().setDAOFactory(df);
     }
 
     @After
@@ -108,7 +123,6 @@
         backends = null;
         config = null;
         configLoader = null;
-        storage = null;
     }
 
     @Test
@@ -116,14 +130,14 @@
         /* setup fake backend */
         backends.add(new BackendID("mock", MockBackend.class.getName()));
 
-        BackendRegistry registry = new BackendRegistry(config, configLoader, storage);
+        BackendRegistry registry = new BackendRegistry(config, configLoader);
         assertEquals(1, registry.getAll().size());
         assertNotNull(registry.getByName("mock"));
     }
 
     @Test
     public void testNoBackendsRegistered() throws InvalidConfigurationException, BackendLoadException {
-        BackendRegistry registry = new BackendRegistry(config, configLoader, storage);
+        BackendRegistry registry = new BackendRegistry(config, configLoader);
         assertEquals(0, registry.getAll().size());
         assertEquals(null, registry.getByName("system"));
         assertEquals(null, registry.getByName("mock"));
@@ -137,7 +151,7 @@
         backends.add(new BackendID("mock", MockBackend.class.getClass().getName()));
 
         /* load the backends */
-        new BackendRegistry(config, configLoader, storage);
+        new BackendRegistry(config, configLoader);
     }
 
 }
--- a/agent/src/test/java/com/redhat/thermostat/backend/system/JvmStatHostListenerTest.java	Thu Apr 12 10:37:36 2012 -0400
+++ b/agent/src/test/java/com/redhat/thermostat/backend/system/JvmStatHostListenerTest.java	Thu Apr 12 10:38:24 2012 -0400
@@ -48,6 +48,10 @@
 import org.junit.Test;
 import org.mockito.Matchers;
 
+import com.redhat.thermostat.common.dao.DAOFactory;
+import com.redhat.thermostat.common.dao.VmClassStatDAO;
+import com.redhat.thermostat.common.dao.VmInfoDAO;
+
 import sun.jvmstat.monitor.HostIdentifier;
 import sun.jvmstat.monitor.MonitoredHost;
 import sun.jvmstat.monitor.MonitoredVm;
@@ -75,10 +79,14 @@
         when(host.getMonitoredVm(any(VmIdentifier.class))).thenReturn(vm);
         when(vmEvent.getMonitoredHost()).thenReturn(host);
 
-        JvmStatHostListener l = new JvmStatHostListener();
+        VmClassStatDAO vmClassDAO = mock(VmClassStatDAO.class);
+        VmInfoDAO vmInfoDAO = mock(VmInfoDAO.class);
+        DAOFactory df = mock(DAOFactory.class);
+        when(df.getVmClassStatsDAO()).thenReturn(vmClassDAO);
+        when(df.getVmInfoDAO()).thenReturn(vmInfoDAO);
+        JvmStatHostListener l = new JvmStatHostListener(df, true);
         SystemBackend backend = mock(SystemBackend.class);
         when(backend.getObserveNewJvm()).thenReturn(true);
-        l.setBackend(backend);
 
         l.vmStatusChanged(vmEvent);
 
--- a/agent/src/test/java/com/redhat/thermostat/backend/system/JvmStatVmClassListenerTest.java	Thu Apr 12 10:37:36 2012 -0400
+++ b/agent/src/test/java/com/redhat/thermostat/backend/system/JvmStatVmClassListenerTest.java	Thu Apr 12 10:38:24 2012 -0400
@@ -48,42 +48,52 @@
 import sun.jvmstat.monitor.MonitoredVm;
 import sun.jvmstat.monitor.event.VmEvent;
 
+import com.redhat.thermostat.common.dao.DAOFactory;
+import com.redhat.thermostat.common.dao.VmClassStatDAO;
+import com.redhat.thermostat.common.model.VmClassStat;
 import com.redhat.thermostat.common.storage.Chunk;
 import com.redhat.thermostat.common.storage.Key;
+import com.redhat.thermostat.common.storage.Storage;
 
 public class JvmStatVmClassListenerTest {
 
+    private static final Integer VM_ID = 123;
+    private static final Long LOADED_CLASSES = 1234L;
+
     @Test
     public void testMonitorUpdatedClassStat() throws Exception {
 
-        SystemBackend backend = mock(SystemBackend.class);
-        int vmId = 123;
-        JvmStatVmClassListener l = new JvmStatVmClassListener(backend, vmId);
+        VmClassStatDAO dao = mock(VmClassStatDAO.class);
+        DAOFactory df = mock(DAOFactory.class);
+        when(df.getVmClassStatsDAO()).thenReturn(dao);
+        JvmStatVmClassListener l = new JvmStatVmClassListener(df, VM_ID);
         VmEvent vmEvent = mock(VmEvent.class);
         MonitoredVm monitoredVm = mock(MonitoredVm.class);
         Monitor m = mock(Monitor.class);
-        when(m.getValue()).thenReturn(new Long(1234));
+        when(m.getValue()).thenReturn(LOADED_CLASSES);
         when(monitoredVm.findByName("java.cls.loadedClasses")).thenReturn(m);
         when(vmEvent.getMonitoredVm()).thenReturn(monitoredVm);
 
         l.monitorsUpdated(vmEvent);
 
-        ArgumentCaptor<Chunk> chunkArg = ArgumentCaptor.forClass(Chunk.class);
-        verify(backend).store(chunkArg.capture());
-        assertEquals((Long) 1234L, chunkArg.getValue().get(new Key<Long>("loadedClasses", false)));
-        assertEquals((Integer) 123, chunkArg.getValue().get(new Key<Integer>("vm-id", false)));
+        ArgumentCaptor<VmClassStat> arg = ArgumentCaptor.forClass(VmClassStat.class);
+        verify(dao).putVmClassStat(arg.capture());
+        VmClassStat stat = arg.getValue();
+        assertEquals(LOADED_CLASSES, (Long) stat.getLoadedClasses());
+        assertEquals(VM_ID, (Integer) stat.getVmId());
     }
 
     @Test
     public void testMonitorUpdatedClassStatTwice() throws Exception {
 
-        SystemBackend backend = mock(SystemBackend.class);
-        int vmId = 123;
-        JvmStatVmClassListener l = new JvmStatVmClassListener(backend, vmId);
+        VmClassStatDAO dao = mock(VmClassStatDAO.class);
+        DAOFactory df = mock(DAOFactory.class);
+        when(df.getVmClassStatsDAO()).thenReturn(dao);
+        JvmStatVmClassListener l = new JvmStatVmClassListener(df, VM_ID);
         VmEvent vmEvent = mock(VmEvent.class);
         MonitoredVm monitoredVm = mock(MonitoredVm.class);
         Monitor m = mock(Monitor.class);
-        when(m.getValue()).thenReturn(new Long(1234));
+        when(m.getValue()).thenReturn(LOADED_CLASSES);
         when(monitoredVm.findByName("java.cls.loadedClasses")).thenReturn(m);
         when(vmEvent.getMonitoredVm()).thenReturn(monitoredVm);
 
--- a/agent/src/test/java/com/redhat/thermostat/backend/system/SystemBackendTest.java	Thu Apr 12 10:37:36 2012 -0400
+++ b/agent/src/test/java/com/redhat/thermostat/backend/system/SystemBackendTest.java	Thu Apr 12 10:38:24 2012 -0400
@@ -39,6 +39,7 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 import java.util.Collection;
 
@@ -46,6 +47,7 @@
 import org.junit.Test;
 
 import com.redhat.thermostat.common.dao.CpuStatDAO;
+import com.redhat.thermostat.common.dao.DAOFactory;
 import com.redhat.thermostat.common.dao.HostInfoDAO;
 import com.redhat.thermostat.common.dao.MemoryStatDAO;
 import com.redhat.thermostat.common.dao.NetworkInterfaceInfoDAO;
@@ -63,9 +65,21 @@
 
     @Before
     public void setUp() {
+        Storage s = mock(Storage.class);
+        CpuStatDAO cDAO = mock(CpuStatDAO.class);
+        HostInfoDAO hDAO = mock(HostInfoDAO.class);
+        MemoryStatDAO mDAO = mock(MemoryStatDAO.class);
+        VmCpuStatDAO vDAO = mock(VmCpuStatDAO.class);
+        NetworkInterfaceInfoDAO nDAO = mock(NetworkInterfaceInfoDAO.class);
+        DAOFactory df = mock(DAOFactory.class);
+        when(df.getStorage()).thenReturn(s);
+        when(df.getCpuStatDAO()).thenReturn(cDAO);
+        when(df.getHostInfoDAO()).thenReturn(hDAO);
+        when(df.getMemoryStatDAO()).thenReturn(mDAO);
+        when(df.getVmCpuStatDAO()).thenReturn(vDAO);
+        when(df.getNetworkInterfaceInfoDAO()).thenReturn(nDAO);
         b = new SystemBackend();
-        Storage s = mock(Storage.class);
-        b.setStorage(s);
+        b.setDAOFactory(df);
     }
 
     @Test
--- a/common/src/main/java/com/redhat/thermostat/common/dao/CpuStatDAOImpl.java	Thu Apr 12 10:37:36 2012 -0400
+++ b/common/src/main/java/com/redhat/thermostat/common/dao/CpuStatDAOImpl.java	Thu Apr 12 10:38:24 2012 -0400
@@ -66,12 +66,12 @@
     }
 
     @Override
-    public long getCount() {
-        return storage.getCount(cpuStatCategory);
+    public void putCpuStat(CpuStat stat) {
+        storage.putChunk(converter.toChunk(stat));
     }
 
     @Override
-    public void putCpuStat(CpuStat stat) {
-        storage.putChunk(converter.toChunk(stat));
+    public long getCount() {
+        return storage.getCount(cpuStatCategory);
     }
 }
--- a/common/src/main/java/com/redhat/thermostat/common/dao/HostInfoDAO.java	Thu Apr 12 10:37:36 2012 -0400
+++ b/common/src/main/java/com/redhat/thermostat/common/dao/HostInfoDAO.java	Thu Apr 12 10:38:24 2012 -0400
@@ -57,5 +57,7 @@
 
     HostInfo getHostInfo(HostRef ref);
 
+    void putHostInfo(HostInfo info);
+
     Collection<HostRef> getHosts();
 }
--- a/common/src/main/java/com/redhat/thermostat/common/dao/HostInfoDAOImpl.java	Thu Apr 12 10:37:36 2012 -0400
+++ b/common/src/main/java/com/redhat/thermostat/common/dao/HostInfoDAOImpl.java	Thu Apr 12 10:38:24 2012 -0400
@@ -63,6 +63,11 @@
     }
 
     @Override
+    public void putHostInfo(HostInfo info) {
+        storage.putChunk(converter.toChunk(info));
+    }
+
+    @Override
     public Collection<HostRef> getHosts() {
         Collection<HostRef> hosts = new ArrayList<HostRef>();
         Cursor hostsCursor = storage.findAllFromCategory(hostInfoCategory);
--- a/common/src/main/java/com/redhat/thermostat/common/dao/MemoryStatDAO.java	Thu Apr 12 10:37:36 2012 -0400
+++ b/common/src/main/java/com/redhat/thermostat/common/dao/MemoryStatDAO.java	Thu Apr 12 10:38:24 2012 -0400
@@ -57,4 +57,6 @@
             memoryCachedKey, memorySwapTotalKey, memorySwapFreeKey, memoryCommitLimitKey);
 
     public List<MemoryStat> getLatestMemoryStats(HostRef ref);
+
+    void putMemoryStat(MemoryStat stat);
 }
--- a/common/src/main/java/com/redhat/thermostat/common/dao/MemoryStatDAOImpl.java	Thu Apr 12 10:37:36 2012 -0400
+++ b/common/src/main/java/com/redhat/thermostat/common/dao/MemoryStatDAOImpl.java	Thu Apr 12 10:38:24 2012 -0400
@@ -66,6 +66,11 @@
     }
 
     @Override
+    public void putMemoryStat(MemoryStat stat) {
+        storage.putChunk(converter.toChunk(stat));
+    }
+
+    @Override
     public long getCount() {
         return storage.getCount(memoryStatCategory);
     }
--- a/common/src/main/java/com/redhat/thermostat/common/dao/NetworkInterfaceInfoDAO.java	Thu Apr 12 10:37:36 2012 -0400
+++ b/common/src/main/java/com/redhat/thermostat/common/dao/NetworkInterfaceInfoDAO.java	Thu Apr 12 10:38:24 2012 -0400
@@ -52,4 +52,6 @@
             Key.AGENT_ID, Key.TIMESTAMP, ifaceKey, ip4AddrKey, ip6AddrKey);
 
     public List<NetworkInterfaceInfo> getNetworkInterfaces(HostRef ref);
+
+    public void putNetworkInterfaceInfo(NetworkInterfaceInfo info);
 }
--- a/common/src/main/java/com/redhat/thermostat/common/dao/NetworkInterfaceInfoDAOImpl.java	Thu Apr 12 10:37:36 2012 -0400
+++ b/common/src/main/java/com/redhat/thermostat/common/dao/NetworkInterfaceInfoDAOImpl.java	Thu Apr 12 10:38:24 2012 -0400
@@ -48,9 +48,11 @@
 class NetworkInterfaceInfoDAOImpl implements NetworkInterfaceInfoDAO {
 
     private Storage storage;
+    private NetworkInterfaceInfoConverter converter;
 
     NetworkInterfaceInfoDAOImpl(Storage storage) {
         this.storage = storage;
+        converter = new NetworkInterfaceInfoConverter();
     }
 
     @Override
@@ -59,7 +61,6 @@
         query.put(Key.AGENT_ID, ref.getAgentId());
 
         Cursor cursor = storage.findAll(query);
-        NetworkInterfaceInfoConverter converter = new NetworkInterfaceInfoConverter();
         List<NetworkInterfaceInfo> result = new ArrayList<>();
         while (cursor.hasNext()) {
             Chunk chunk = cursor.next();
@@ -69,4 +70,9 @@
         return result;
     }
 
+    @Override
+    public void putNetworkInterfaceInfo(NetworkInterfaceInfo info) {
+        storage.putChunk(converter.toChunk(info));
+    }
+
 }
--- a/common/src/main/java/com/redhat/thermostat/common/dao/VmClassStatDAO.java	Thu Apr 12 10:37:36 2012 -0400
+++ b/common/src/main/java/com/redhat/thermostat/common/dao/VmClassStatDAO.java	Thu Apr 12 10:38:24 2012 -0400
@@ -51,4 +51,6 @@
 
     public List<VmClassStat> getLatestClassStats(VmRef ref);
 
+    public void putVmClassStat(VmClassStat stat);
+
 }
\ No newline at end of file
--- a/common/src/main/java/com/redhat/thermostat/common/dao/VmClassStatDAOImpl.java	Thu Apr 12 10:37:36 2012 -0400
+++ b/common/src/main/java/com/redhat/thermostat/common/dao/VmClassStatDAOImpl.java	Thu Apr 12 10:38:24 2012 -0400
@@ -64,4 +64,9 @@
         }
         return getter.getLatest();
     }
+
+    @Override
+    public void putVmClassStat(VmClassStat stat) {
+        storage.putChunk(converter.toChunk(stat));
+    }
 }
--- a/common/src/main/java/com/redhat/thermostat/common/dao/VmCpuStatDAO.java	Thu Apr 12 10:37:36 2012 -0400
+++ b/common/src/main/java/com/redhat/thermostat/common/dao/VmCpuStatDAO.java	Thu Apr 12 10:38:24 2012 -0400
@@ -51,4 +51,6 @@
 
     public abstract List<VmCpuStat> getLatestVmCpuStats(VmRef ref);
 
+    public abstract void putVmCpuStat(VmCpuStat stat);
+
 }
--- a/common/src/main/java/com/redhat/thermostat/common/dao/VmCpuStatDAOImpl.java	Thu Apr 12 10:37:36 2012 -0400
+++ b/common/src/main/java/com/redhat/thermostat/common/dao/VmCpuStatDAOImpl.java	Thu Apr 12 10:38:24 2012 -0400
@@ -64,4 +64,9 @@
         }
         return getter.getLatest();
     }
+
+    @Override
+    public void putVmCpuStat(VmCpuStat stat) {
+        storage.putChunk(converter.toChunk(stat));
+    }
 }
--- a/common/src/main/java/com/redhat/thermostat/common/dao/VmGcStatDAO.java	Thu Apr 12 10:37:36 2012 -0400
+++ b/common/src/main/java/com/redhat/thermostat/common/dao/VmGcStatDAO.java	Thu Apr 12 10:38:24 2012 -0400
@@ -54,4 +54,6 @@
             runCountKey, wallTimeKey);
 
     public List<VmGcStat> getLatestVmGcStats(VmRef ref);
+
+    public void putVmGcStat(VmGcStat stat);
 }
--- a/common/src/main/java/com/redhat/thermostat/common/dao/VmGcStatDAOImpl.java	Thu Apr 12 10:37:36 2012 -0400
+++ b/common/src/main/java/com/redhat/thermostat/common/dao/VmGcStatDAOImpl.java	Thu Apr 12 10:38:24 2012 -0400
@@ -65,4 +65,9 @@
         return getter.getLatest();
     }
 
+    @Override
+    public void putVmGcStat(VmGcStat stat) {
+        storage.putChunk(converter.toChunk(stat));
+    }
+
 }
--- a/common/src/main/java/com/redhat/thermostat/common/dao/VmInfoDAO.java	Thu Apr 12 10:37:36 2012 -0400
+++ b/common/src/main/java/com/redhat/thermostat/common/dao/VmInfoDAO.java	Thu Apr 12 10:38:24 2012 -0400
@@ -72,4 +72,8 @@
     public VmInfo getVmInfo(VmRef ref);
 
     Collection<VmRef> getVMs(HostRef host);
+
+    public void putVmInfo(VmInfo info);
+
+    public void putVmStoppedTime(int vmId, long timestamp);
 }
--- a/common/src/main/java/com/redhat/thermostat/common/dao/VmInfoDAOImpl.java	Thu Apr 12 10:37:36 2012 -0400
+++ b/common/src/main/java/com/redhat/thermostat/common/dao/VmInfoDAOImpl.java	Thu Apr 12 10:38:24 2012 -0400
@@ -102,4 +102,21 @@
     public long getCount() {
         return storage.getCount(vmInfoCategory);
     }
+
+    @Override
+    public void putVmInfo(VmInfo info) {
+        storage.putChunk(converter.toChunk(info));
+    }
+
+    @Override
+    public void putVmStoppedTime(int vmId, long timestamp) {
+        storage.updateChunk(makeStoppedChunk(vmId, timestamp));
+    }
+
+    private Chunk makeStoppedChunk(int vmId, long stopTimeStamp) {
+        Chunk chunk = new Chunk(VmInfoDAO.vmInfoCategory, false);
+        chunk.put(VmInfoDAO.vmIdKey, vmId);
+        chunk.put(VmInfoDAO.stopTimeKey, stopTimeStamp);
+        return chunk;
+    }
 }
--- a/common/src/main/java/com/redhat/thermostat/common/dao/VmMemoryStatDAO.java	Thu Apr 12 10:37:36 2012 -0400
+++ b/common/src/main/java/com/redhat/thermostat/common/dao/VmMemoryStatDAO.java	Thu Apr 12 10:38:24 2012 -0400
@@ -87,4 +87,6 @@
 
     public VmMemoryStat getLatestMemoryStat(VmRef ref);
 
+    public void putVmMemoryStat(VmMemoryStat stat);
+
 }
--- a/common/src/main/java/com/redhat/thermostat/common/dao/VmMemoryStatDAOImpl.java	Thu Apr 12 10:37:36 2012 -0400
+++ b/common/src/main/java/com/redhat/thermostat/common/dao/VmMemoryStatDAOImpl.java	Thu Apr 12 10:38:24 2012 -0400
@@ -45,9 +45,11 @@
 class VmMemoryStatDAOImpl implements VmMemoryStatDAO {
 
     private final Storage storage;
+    private final VmMemoryStatConverter converter;
 
     VmMemoryStatDAOImpl(Storage storage) {
         this.storage = storage;
+        converter = new VmMemoryStatConverter();
     }
 
     @Override
@@ -57,9 +59,14 @@
         query.put(Key.VM_ID, ref.getId());
         Cursor cursor = storage.findAll(query).sort(Key.TIMESTAMP, Cursor.SortDirection.DESCENDING).limit(1);
         if (cursor.hasNext()) {
-            return new VmMemoryStatConverter().fromChunk(cursor.next());
+            return converter.fromChunk(cursor.next());
         }
         return null;
     }
 
+    @Override
+    public void putVmMemoryStat(VmMemoryStat stat) {
+        storage.putChunk(converter.toChunk(stat));
+    }
+
 }
--- a/common/src/test/java/com/redhat/thermostat/common/dao/CpuStatDAOTest.java	Thu Apr 12 10:37:36 2012 -0400
+++ b/common/src/test/java/com/redhat/thermostat/common/dao/CpuStatDAOTest.java	Thu Apr 12 10:38:24 2012 -0400
@@ -139,6 +139,16 @@
         CpuStat stat = new CpuStat(1, 5.0, 15.0, 10.0);
         CpuStatDAO dao = new CpuStatDAOImpl(storage);
         dao.putCpuStat(stat);
+
+        ArgumentCaptor<Chunk> arg = ArgumentCaptor.forClass(Chunk.class);
+        verify(storage).putChunk(arg.capture());
+        Chunk chunk = arg.getValue();
+
+        assertEquals(CpuStatDAO.cpuStatCategory, chunk.getCategory());
+        assertEquals((Long) 1L, chunk.get(Key.TIMESTAMP));
+        assertEquals((Double) 5.0, chunk.get(CpuStatDAO.cpu5LoadKey));
+        assertEquals((Double) 15.0, chunk.get(CpuStatDAO.cpu10LoadKey));
+        assertEquals((Double) 10.0, chunk.get(CpuStatDAO.cpu15LoadKey));
     }
 
     @Test
--- a/common/src/test/java/com/redhat/thermostat/common/dao/HostInfoDAOTest.java	Thu Apr 12 10:37:36 2012 -0400
+++ b/common/src/test/java/com/redhat/thermostat/common/dao/HostInfoDAOTest.java	Thu Apr 12 10:38:24 2012 -0400
@@ -43,9 +43,11 @@
 import java.util.Collection;
 
 import org.junit.Test;
+import org.mockito.ArgumentCaptor;
 
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import com.redhat.thermostat.common.model.HostInfo;
@@ -57,6 +59,13 @@
 
 public class HostInfoDAOTest {
 
+    private static final String HOST_NAME = "a host name";
+    private static final String OS_NAME = "some os";
+    private static final String OS_KERNEL = "some kernel";
+    private static final String CPU_MODEL = "some cpu that runs fast";
+    private static final int CPU_NUM = -1;
+    private static final long MEMORY_TOTAL = 0xCAFEBABEl;
+
     @Test
     public void testCategory() {
         assertEquals("host-info", HostInfoDAO.hostInfoCategory.getName());
@@ -73,12 +82,6 @@
 
     @Test
     public void testGetHostInfo() {
-        final String HOST_NAME = "a host name";
-        final String OS_NAME = "some os";
-        final String OS_KERNEL = "some kernel";
-        final String CPU_MODEL = "some cpu that runs fast";
-        final int CPU_NUM = -1;
-        final long MEMORY_TOTAL = 0xCAFEBABEl;
 
         Chunk chunk = new Chunk(HostInfoDAO.hostInfoCategory, false);
         chunk.put(HostInfoDAO.hostNameKey, HOST_NAME);
@@ -166,6 +169,26 @@
     }
 
     @Test
+    public void testPutHostInfo() {
+        Storage storage = mock(Storage.class);
+        HostInfo info = new HostInfo(HOST_NAME, OS_NAME, OS_KERNEL, CPU_MODEL, CPU_NUM, MEMORY_TOTAL);
+        HostInfoDAO dao = new HostInfoDAOImpl(storage);
+        dao.putHostInfo(info);
+
+        ArgumentCaptor<Chunk> arg = ArgumentCaptor.forClass(Chunk.class);
+        verify(storage).putChunk(arg.capture());
+        Chunk chunk = arg.getValue();
+
+        assertEquals(HostInfoDAO.hostInfoCategory, chunk.getCategory());
+        assertEquals(HOST_NAME, chunk.get(HostInfoDAO.hostNameKey));
+        assertEquals(OS_NAME, chunk.get(HostInfoDAO.osNameKey));
+        assertEquals(OS_KERNEL, chunk.get(HostInfoDAO.osKernelKey));
+        assertEquals(CPU_MODEL, chunk.get(HostInfoDAO.cpuModelKey));
+        assertEquals((Integer) CPU_NUM, chunk.get(HostInfoDAO.cpuCountKey));
+        assertEquals((Long) MEMORY_TOTAL, chunk.get(HostInfoDAO.hostMemoryTotalKey));
+    }
+
+    @Test
     public void testGetCount() {
         Storage storage = mock(Storage.class);
         when(storage.getCount(any(Category.class))).thenReturn(5L);
--- a/common/src/test/java/com/redhat/thermostat/common/dao/MemoryStatDAOTest.java	Thu Apr 12 10:37:36 2012 -0400
+++ b/common/src/test/java/com/redhat/thermostat/common/dao/MemoryStatDAOTest.java	Thu Apr 12 10:38:24 2012 -0400
@@ -59,6 +59,17 @@
 import com.redhat.thermostat.common.storage.Storage;
 
 public class MemoryStatDAOTest {
+
+
+    private static long TIMESTAMP = 1;
+    private static long TOTAL = 2;
+    private static long FREE = 3;
+    private static long BUFFERS = 4;
+    private static long CACHED = 5;
+    private static long SWAP_TOTAL = 6;
+    private static long SWAP_FREE = 7;
+    private static long COMMIT_LIMIT = 8;
+
     @Test
     public void testCategory() {
         assertEquals("memory-stats", MemoryStatDAO.memoryStatCategory.getName());
@@ -78,14 +89,6 @@
 
     @Test
     public void testGetLatestMemoryStats() {
-        long TIMESTAMP = 1;
-        long TOTAL = 2;
-        long FREE = 3;
-        long BUFFERS = 4;
-        long CACHED = 5;
-        long SWAP_TOTAL = 6;
-        long SWAP_FREE = 7;
-        long COMMIT_LIMIT = 8;
 
         Chunk chunk = new Chunk(MemoryStatDAO.memoryStatCategory, false);
         chunk.put(Key.TIMESTAMP, TIMESTAMP);
@@ -129,14 +132,6 @@
 
     @Test
     public void testGetLatestMemoryStatsTwice() {
-        long TIMESTAMP = 1;
-        long TOTAL = 2;
-        long FREE = 3;
-        long BUFFERS = 4;
-        long CACHED = 5;
-        long SWAP_TOTAL = 6;
-        long SWAP_FREE = 7;
-        long COMMIT_LIMIT = 8;
 
         Chunk chunk = new Chunk(MemoryStatDAO.memoryStatCategory, false);
         chunk.put(Key.TIMESTAMP, TIMESTAMP);
@@ -168,6 +163,28 @@
     }
 
     @Test
+    public void testPutHostInfo() {
+        Storage storage = mock(Storage.class);
+        MemoryStat stat = new MemoryStat(TIMESTAMP, TOTAL, FREE, BUFFERS, CACHED, SWAP_TOTAL, SWAP_FREE, COMMIT_LIMIT);
+        MemoryStatDAO dao = new MemoryStatDAOImpl(storage);
+        dao.putMemoryStat(stat);
+
+        ArgumentCaptor<Chunk> arg = ArgumentCaptor.forClass(Chunk.class);
+        verify(storage).putChunk(arg.capture());
+        Chunk chunk = arg.getValue();
+
+        assertEquals(MemoryStatDAO.memoryStatCategory, chunk.getCategory());
+        assertEquals((Long) TIMESTAMP, chunk.get(Key.TIMESTAMP));
+        assertEquals((Long) TOTAL, chunk.get(MemoryStatDAO.memoryTotalKey));
+        assertEquals((Long) FREE, chunk.get(MemoryStatDAO.memoryFreeKey));
+        assertEquals((Long) BUFFERS, chunk.get(MemoryStatDAO.memoryBuffersKey));
+        assertEquals((Long) CACHED, chunk.get(MemoryStatDAO.memoryCachedKey));
+        assertEquals((Long) SWAP_TOTAL, chunk.get(MemoryStatDAO.memorySwapTotalKey));
+        assertEquals((Long) SWAP_FREE, chunk.get(MemoryStatDAO.memorySwapFreeKey));
+        assertEquals((Long) COMMIT_LIMIT, chunk.get(MemoryStatDAO.memoryCommitLimitKey));
+    }
+
+    @Test
     public void testGetCount() {
         Storage storage = mock(Storage.class);
         when(storage.getCount(any(Category.class))).thenReturn(5L);
--- a/common/src/test/java/com/redhat/thermostat/common/dao/NetworkInterfaceInfoDAOTest.java	Thu Apr 12 10:37:36 2012 -0400
+++ b/common/src/test/java/com/redhat/thermostat/common/dao/NetworkInterfaceInfoDAOTest.java	Thu Apr 12 10:38:24 2012 -0400
@@ -59,6 +59,10 @@
 
 public class NetworkInterfaceInfoDAOTest {
 
+    private static final String INTERFACE_NAME = "some interface. maybe eth0";
+    private static final String IPV4_ADDR = "256.256.256.256";
+    private static final String IPV6_ADDR = "100:100:100::::1";
+
     @Test
     public void testCategory() {
         Collection<Key<?>> keys;
@@ -75,9 +79,6 @@
 
     @Test
     public void testGetNetworkInterfaces() {
-        final String INTERFACE_NAME = "some interface. maybe eth0";
-        final String IPV4_ADDR = "256.256.256.256";
-        final String IPV6_ADDR = "100:100:100::::1";
 
         Chunk chunk = new Chunk(NetworkInterfaceInfoDAO.networkInfoCategory, false);
         chunk.put(NetworkInterfaceInfoDAO.ifaceKey, INTERFACE_NAME);
@@ -109,4 +110,23 @@
         assertEquals(IPV4_ADDR, info.getIp4Addr());
         assertEquals(IPV6_ADDR, info.getIp6Addr());
     }
+
+    @Test
+    public void testPutNetworkInterfaceInfo() {
+        Storage storage = mock(Storage.class);
+        NetworkInterfaceInfo info = new NetworkInterfaceInfo(INTERFACE_NAME);
+        info.setIp4Addr(IPV4_ADDR);
+        info.setIp6Addr(IPV6_ADDR);
+        NetworkInterfaceInfoDAO dao = new NetworkInterfaceInfoDAOImpl(storage);
+        dao.putNetworkInterfaceInfo(info);
+
+        ArgumentCaptor<Chunk> arg = ArgumentCaptor.forClass(Chunk.class);
+        verify(storage).putChunk(arg.capture());
+        Chunk chunk = arg.getValue();
+
+        assertEquals(NetworkInterfaceInfoDAO.networkInfoCategory, chunk.getCategory());
+        assertEquals(INTERFACE_NAME, chunk.get(NetworkInterfaceInfoDAO.ifaceKey));
+        assertEquals(IPV4_ADDR, chunk.get(NetworkInterfaceInfoDAO.ip4AddrKey));
+        assertEquals(IPV6_ADDR, chunk.get(NetworkInterfaceInfoDAO.ip6AddrKey));
+    }
 }
--- a/common/src/test/java/com/redhat/thermostat/common/dao/VmClassStatDAOTest.java	Thu Apr 12 10:37:36 2012 -0400
+++ b/common/src/test/java/com/redhat/thermostat/common/dao/VmClassStatDAOTest.java	Thu Apr 12 10:38:24 2012 -0400
@@ -59,6 +59,10 @@
 
 public class VmClassStatDAOTest {
 
+    private static final Long TIMESTAMP = 1234L;
+    private static final Integer VM_ID = 123;
+    private static final Long LOADED_CLASSES = 12345L;
+
     @Test
     public void testCategory() {
         assertEquals("vm-class-stats", VmClassStatDAO.vmClassStatsCategory.getName());
@@ -74,10 +78,7 @@
     @Test
     public void testGetLatestClassStatsBasic() {
 
-        Chunk chunk = new Chunk(VmClassStatDAO.vmClassStatsCategory, false);
-        chunk.put(Key.TIMESTAMP, 1234L);
-        chunk.put(Key.VM_ID, 321);
-        chunk.put(VmClassStatDAO.loadedClassesKey, 12345L);
+        Chunk chunk = getChunk();
 
         Cursor cursor = mock(Cursor.class);
         when(cursor.hasNext()).thenReturn(true).thenReturn(false);
@@ -103,18 +104,15 @@
 
         assertEquals(1, vmClassStats.size());
         VmClassStat stat = vmClassStats.get(0);
-        assertEquals(1234L, stat.getTimeStamp());
-        assertEquals(12345L, stat.getLoadedClasses());
-        assertEquals(321, stat.getVmId());
+        assertEquals(TIMESTAMP, (Long) stat.getTimeStamp());
+        assertEquals(LOADED_CLASSES, (Long) stat.getLoadedClasses());
+        assertEquals(VM_ID, (Integer) stat.getVmId());
     }
 
     @Test
     public void testGetLatestClassStatsTwice() {
 
-        Chunk chunk = new Chunk(VmClassStatDAO.vmClassStatsCategory, false);
-        chunk.put(Key.TIMESTAMP, 1234L);
-        chunk.put(Key.VM_ID, 321);
-        chunk.put(VmClassStatDAO.loadedClassesKey, 12345L);
+        Chunk chunk = getChunk();
 
         Cursor cursor = mock(Cursor.class);
         when(cursor.hasNext()).thenReturn(true).thenReturn(false);
@@ -139,4 +137,30 @@
         verify(storage, times(2)).findAll(arg.capture());
         assertEquals("this.timestamp > 1234", arg.getValue().get(new Key<String>("$where", false)));
     }
+
+    private Chunk getChunk() {
+        Chunk chunk = new Chunk(VmClassStatDAO.vmClassStatsCategory, false);
+        chunk.put(Key.TIMESTAMP, TIMESTAMP);
+        chunk.put(Key.VM_ID, VM_ID);
+        chunk.put(VmClassStatDAO.loadedClassesKey, LOADED_CLASSES);
+        return chunk;
+    }
+
+    @Test
+    public void testPutVmClassStat() {
+
+        Storage storage = mock(Storage.class);
+        VmClassStat stat = new VmClassStat(VM_ID, TIMESTAMP, LOADED_CLASSES);
+        VmClassStatDAO dao = new VmClassStatDAOImpl(storage);
+        dao.putVmClassStat(stat);
+
+        ArgumentCaptor<Chunk> arg = ArgumentCaptor.forClass(Chunk.class);
+        verify(storage).putChunk(arg.capture());
+        Chunk chunk = arg.getValue();
+
+        assertEquals(VmClassStatDAO.vmClassStatsCategory, chunk.getCategory());
+        assertEquals((Long) TIMESTAMP, chunk.get(Key.TIMESTAMP));
+        assertEquals((Integer) VM_ID, chunk.get(Key.VM_ID));
+        assertEquals((Long) LOADED_CLASSES, chunk.get(VmClassStatDAO.loadedClassesKey));
+    }
 }
--- a/common/src/test/java/com/redhat/thermostat/common/dao/VmCpuStatDAOTest.java	Thu Apr 12 10:37:36 2012 -0400
+++ b/common/src/test/java/com/redhat/thermostat/common/dao/VmCpuStatDAOTest.java	Thu Apr 12 10:38:24 2012 -0400
@@ -48,6 +48,7 @@
 import java.util.Collection;
 import java.util.List;
 
+import org.junit.Before;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 
@@ -59,6 +60,22 @@
 
 public class VmCpuStatDAOTest {
 
+    private static final Long TIMESTAMP = 1234L;
+    private static final String AGENT_ID = "test-agent-id";
+    private static final Integer VM_ID = 321;
+    private static final Double CPU_LOAD = 9.9;
+
+    private Chunk chunk;
+
+    @Before
+    public void setUp() {
+        chunk = new Chunk(VmCpuStatDAO.vmCpuStatCategory, false);
+        chunk.put(Key.TIMESTAMP, TIMESTAMP);
+        chunk.put(Key.AGENT_ID, AGENT_ID);
+        chunk.put(Key.VM_ID, VM_ID);
+        chunk.put(VmCpuStatDAO.vmCpuLoadKey, CPU_LOAD);
+    }
+
     @Test
     public void testCategory() {
         assertEquals("vm-cpu-stats", VmCpuStatDAO.vmCpuStatCategory.getName());
@@ -73,12 +90,6 @@
     @Test
     public void testGetLatestCpuStatsBasic() {
 
-        Chunk chunk = new Chunk(VmCpuStatDAO.vmCpuStatCategory, false);
-        chunk.put(Key.TIMESTAMP, 1234L);
-        chunk.put(Key.AGENT_ID, "test-agent-id");
-        chunk.put(Key.VM_ID, 321);
-        chunk.put(VmCpuStatDAO.vmCpuLoadKey, 9.9);
-
         Cursor cursor = mock(Cursor.class);
         when(cursor.hasNext()).thenReturn(true).thenReturn(false);
         when(cursor.next()).thenReturn(chunk);
@@ -91,7 +102,7 @@
 
         VmRef vmRef = mock(VmRef.class);
         when(vmRef.getAgent()).thenReturn(hostRef);
-        when(vmRef.getId()).thenReturn(321);
+        when(vmRef.getId()).thenReturn(VM_ID);
 
 
         VmCpuStatDAO dao = new VmCpuStatDAOImpl(storage);
@@ -103,20 +114,14 @@
 
         assertEquals(1, vmCpuStats.size());
         VmCpuStat stat = vmCpuStats.get(0);
-        assertEquals(1234L, stat.getTimeStamp());
-        assertEquals(9.9, stat.getCpuLoad(), 0.001);
-        assertEquals(321, stat.getVmId());
+        assertEquals(TIMESTAMP, (Long) stat.getTimeStamp());
+        assertEquals(CPU_LOAD, stat.getCpuLoad(), 0.001);
+        assertEquals(VM_ID, (Integer) stat.getVmId());
     }
 
     @Test
     public void testGetLatestCpuStatsTwice() {
 
-        Chunk chunk = new Chunk(VmCpuStatDAO.vmCpuStatCategory, false);
-        chunk.put(Key.AGENT_ID, "test-agent-id");
-        chunk.put(Key.TIMESTAMP, 1234L);
-        chunk.put(Key.VM_ID, 321);
-        chunk.put(VmCpuStatDAO.vmCpuLoadKey, 9.9);
-
         Cursor cursor = mock(Cursor.class);
         when(cursor.hasNext()).thenReturn(true).thenReturn(false);
         when(cursor.next()).thenReturn(chunk);
@@ -140,4 +145,20 @@
         assertEquals("this.timestamp > 1234", arg.getValue().get(new Key<String>("$where", false)));
     }
 
+    @Test
+    public void testPutVmCpuStat() {
+        Storage storage = mock(Storage.class);
+        VmCpuStat stat = new VmCpuStat(TIMESTAMP, VM_ID, CPU_LOAD);
+        VmCpuStatDAO dao = new VmCpuStatDAOImpl(storage);
+        dao.putVmCpuStat(stat);
+
+        ArgumentCaptor<Chunk> arg = ArgumentCaptor.forClass(Chunk.class);
+        verify(storage).putChunk(arg.capture());
+        Chunk chunk = arg.getValue();
+
+        assertEquals(VmCpuStatDAO.vmCpuStatCategory, chunk.getCategory());
+        assertEquals(TIMESTAMP, chunk.get(Key.TIMESTAMP));
+        assertEquals(VM_ID, chunk.get(Key.VM_ID));
+        assertEquals(CPU_LOAD, chunk.get(VmCpuStatDAO.vmCpuLoadKey));
+    }
 }
--- a/common/src/test/java/com/redhat/thermostat/common/dao/VmGcStatDAOTest.java	Thu Apr 12 10:37:36 2012 -0400
+++ b/common/src/test/java/com/redhat/thermostat/common/dao/VmGcStatDAOTest.java	Thu Apr 12 10:38:24 2012 -0400
@@ -60,6 +60,12 @@
 
 public class VmGcStatDAOTest {
 
+    private static final Integer VM_ID = 123;
+    private static final Long TIMESTAMP = 456L;
+    private static final String COLLECTOR = "collector1";
+    private static final Long RUN_COUNT = 10L;
+    private static final Long WALL_TIME = 9L;
+
     @Test
     public void testCategory() {
         assertEquals("vm-gc-stats", VmGcStatDAO.vmGcStatCategory.getName());
@@ -76,12 +82,6 @@
     @Test
     public void testGetLatestVmGcStatsBasic() {
 
-        final Integer VM_ID = 123;
-        final Long TIMESTAMP = 456L;
-        final String COLLECTOR = "collector1";
-        final Long RUN_COUNT = 10L;
-        final Long WALL_TIME = 9L;
-
         Chunk chunk = new Chunk(VmGcStatDAO.vmGcStatCategory, false);
         chunk.put(Key.TIMESTAMP, TIMESTAMP);
         chunk.put(Key.VM_ID, VM_ID);
@@ -123,12 +123,6 @@
     @Test
     public void testGetLatestVmGcStatsTwice() {
 
-        final Integer VM_ID = 123;
-        final Long TIMESTAMP = 456L;
-        final String COLLECTOR = "collector1";
-        final Long RUN_COUNT = 10L;
-        final Long WALL_TIME = 9L;
-
         Chunk chunk = new Chunk(VmGcStatDAO.vmGcStatCategory, false);
         chunk.put(Key.TIMESTAMP, TIMESTAMP);
         chunk.put(Key.VM_ID, VM_ID);
@@ -158,4 +152,23 @@
         verify(storage, times(2)).findAll(arg.capture());
         assertEquals("this.timestamp > 456", arg.getValue().get(new Key<String>("$where", false)));
     }
+
+    @Test
+    public void testPutVmGcStat() {
+        Storage storage = mock(Storage.class);
+        VmGcStat stat = new VmGcStat(VM_ID, TIMESTAMP, COLLECTOR, RUN_COUNT, WALL_TIME);
+        VmGcStatDAO dao = new VmGcStatDAOImpl(storage);
+        dao.putVmGcStat(stat);
+
+        ArgumentCaptor<Chunk> arg = ArgumentCaptor.forClass(Chunk.class);
+        verify(storage).putChunk(arg.capture());
+        Chunk chunk = arg.getValue();
+
+        assertEquals(VmGcStatDAO.vmGcStatCategory, chunk.getCategory());
+        assertEquals(TIMESTAMP, chunk.get(Key.TIMESTAMP));
+        assertEquals(VM_ID, chunk.get(Key.VM_ID));
+        assertEquals(COLLECTOR, chunk.get(VmGcStatDAO.collectorKey));
+        assertEquals(RUN_COUNT, chunk.get(VmGcStatDAO.runCountKey));
+        assertEquals(WALL_TIME, chunk.get(VmGcStatDAO.wallTimeKey));
+    }
 }
--- a/common/src/test/java/com/redhat/thermostat/common/dao/VmInfoDAOTest.java	Thu Apr 12 10:37:36 2012 -0400
+++ b/common/src/test/java/com/redhat/thermostat/common/dao/VmInfoDAOTest.java	Thu Apr 12 10:38:24 2012 -0400
@@ -41,6 +41,7 @@
 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.util.ArrayList;
@@ -52,6 +53,7 @@
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.ArgumentCaptor;
 
 import com.redhat.thermostat.common.model.VmInfo;
 import com.redhat.thermostat.common.storage.Category;
@@ -237,4 +239,50 @@
         Long count = dao.getCount();
         assertEquals((Long) 5L, count);
     }
+
+    @Test
+    public void testPutVmInfo() {
+
+        Storage storage = mock(Storage.class);
+        VmInfo info = new VmInfo(vmId, startTime, stopTime, jVersion, jHome,
+                mainClass, commandLine, vmName, vmInfo, vmVersion, vmArgs,
+                props, env, libs);
+        VmInfoDAO dao = new VmInfoDAOImpl(storage);
+        dao.putVmInfo(info);
+
+        ArgumentCaptor<Chunk> arg = ArgumentCaptor.forClass(Chunk.class);
+        verify(storage).putChunk(arg.capture());
+        Chunk chunk = arg.getValue();
+
+        assertEquals(VmInfoDAO.vmInfoCategory, chunk.getCategory());
+        assertEquals((Integer) vmId, chunk.get(VmInfoDAO.vmIdKey));
+        assertEquals((Long) startTime, chunk.get(VmInfoDAO.startTimeKey));
+        assertEquals((Long) stopTime, chunk.get(VmInfoDAO.stopTimeKey));
+        assertEquals(jVersion, chunk.get(VmInfoDAO.runtimeVersionKey));
+        assertEquals(jHome, chunk.get(VmInfoDAO.javaHomeKey));
+        assertEquals(mainClass, chunk.get(VmInfoDAO.mainClassKey));
+        assertEquals(commandLine, chunk.get(VmInfoDAO.commandLineKey));
+        assertEquals(vmName, chunk.get(VmInfoDAO.vmNameKey));
+        assertEquals(vmInfo, chunk.get(VmInfoDAO.vmInfoKey));
+        assertEquals(vmVersion, chunk.get(VmInfoDAO.vmVersionKey));
+        assertEquals(vmArgs, chunk.get(VmInfoDAO.vmArgumentsKey));
+        assertEquals(props, chunk.get(VmInfoDAO.propertiesKey));
+        assertEquals(env, chunk.get(VmInfoDAO.environmentKey));
+        assertEquals(libs, chunk.get(VmInfoDAO.librariesKey));
+    }
+
+    @Test
+    public void testPutVmStoppedTime() {
+        Storage storage = mock(Storage.class);
+        VmInfoDAO dao = new VmInfoDAOImpl(storage);
+        dao.putVmStoppedTime(vmId, stopTime);
+
+        ArgumentCaptor<Chunk> arg = ArgumentCaptor.forClass(Chunk.class);
+        verify(storage).updateChunk(arg.capture());
+        Chunk chunk = arg.getValue();
+
+        assertEquals(VmInfoDAO.vmInfoCategory, chunk.getCategory());
+        assertEquals((Integer) vmId, chunk.get(VmInfoDAO.vmIdKey));
+        assertEquals((Long) stopTime, chunk.get(VmInfoDAO.stopTimeKey));
+    }
 }
--- a/common/src/test/java/com/redhat/thermostat/common/dao/VmMemoryStatDAOTest.java	Thu Apr 12 10:37:36 2012 -0400
+++ b/common/src/test/java/com/redhat/thermostat/common/dao/VmMemoryStatDAOTest.java	Thu Apr 12 10:38:24 2012 -0400
@@ -43,7 +43,9 @@
 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.Test;
 import org.mockito.ArgumentCaptor;
@@ -51,6 +53,8 @@
 import org.mockito.stubbing.Answer;
 
 import com.redhat.thermostat.common.model.VmMemoryStat;
+import com.redhat.thermostat.common.model.VmMemoryStat.Generation;
+import com.redhat.thermostat.common.model.VmMemoryStat.Space;
 import com.redhat.thermostat.common.storage.Chunk;
 import com.redhat.thermostat.common.storage.Cursor;
 import com.redhat.thermostat.common.storage.Cursor.SortDirection;
@@ -164,4 +168,75 @@
         VmMemoryStat latest = impl.getLatestMemoryStat(vmRef);
         assertTrue(latest == null);
     }
+
+    @Test
+    public void testPutVmMemoryStat() {
+
+        List<Generation> generations = new ArrayList<Generation>();
+
+        int i = 0;
+        for (String genName: new String[] { "new", "old", "perm" }) {
+            Generation gen = new Generation();
+            gen.name = genName;
+            gen.collector = gen.name;
+            generations.add(gen);
+            List<Space> spaces = new ArrayList<Space>();
+            gen.spaces = spaces;
+            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.name = spaceName;
+                space.index = 0;
+                space.used = i++;
+                space.capacity = i++;
+                space.maxCapacity = i++;
+                spaces.add(space);
+            }
+        }
+        VmMemoryStat stat = new VmMemoryStat(1, 2, generations);
+
+        Storage storage = mock(Storage.class);
+        VmMemoryStatDAO dao = new VmMemoryStatDAOImpl(storage);
+        dao.putVmMemoryStat(stat);
+
+        ArgumentCaptor<Chunk> arg = ArgumentCaptor.forClass(Chunk.class);
+        verify(storage).putChunk(arg.capture());
+        Chunk chunk = arg.getValue();
+
+        assertEquals(VmMemoryStatDAO.vmMemoryStatsCategory, chunk.getCategory());
+        assertEquals((Long) 1l, chunk.get(new Key<Long>("timestamp", false)));
+        assertEquals((Integer) 2, chunk.get(new Key<Integer>("vm-id", false)));
+        assertEquals("new", chunk.get(new Key<String>("eden.gen", false)));
+        assertEquals("new", chunk.get(new Key<String>("eden.collector", false)));
+        assertEquals((Long) 0l, chunk.get(new Key<Long>("eden.used", false)));
+        assertEquals((Long) 1l, chunk.get(new Key<Long>("eden.capacity", false)));
+        assertEquals((Long) 2l, chunk.get(new Key<Long>("eden.max-capacity", false)));
+        assertEquals("new", chunk.get(new Key<String>("s0.gen", false)));
+        assertEquals("new", chunk.get(new Key<String>("s0.collector", false)));
+        assertEquals((Long) 3l, chunk.get(new Key<Long>("s0.used", false)));
+        assertEquals((Long) 4l, chunk.get(new Key<Long>("s0.capacity", false)));
+        assertEquals((Long) 5l, chunk.get(new Key<Long>("s0.max-capacity", false)));
+        assertEquals("new", chunk.get(new Key<String>("s1.gen", false)));
+        assertEquals("new", chunk.get(new Key<String>("s1.collector", false)));
+        assertEquals((Long) 6l, chunk.get(new Key<Long>("s1.used", false)));
+        assertEquals((Long) 7l, chunk.get(new Key<Long>("s1.capacity", false)));
+        assertEquals((Long) 8l, chunk.get(new Key<Long>("s1.max-capacity", false)));
+        assertEquals("old", chunk.get(new Key<String>("old.gen", false)));
+        assertEquals("old", chunk.get(new Key<String>("old.collector", false)));
+        assertEquals((Long) 9l, chunk.get(new Key<Long>("old.used", false)));
+        assertEquals((Long) 10l, chunk.get(new Key<Long>("old.capacity", false)));
+        assertEquals((Long) 11l, chunk.get(new Key<Long>("old.max-capacity", false)));
+        assertEquals("perm", chunk.get(new Key<String>("perm.gen", false)));
+        assertEquals("perm", chunk.get(new Key<String>("perm.collector", false)));
+        assertEquals((Long) 12l, chunk.get(new Key<Long>("perm.used", false)));
+        assertEquals((Long) 13l, chunk.get(new Key<Long>("perm.capacity", false)));
+        assertEquals((Long) 14l, chunk.get(new Key<Long>("perm.max-capacity", false)));
+    }
 }