changeset 609:430be1123985

Implement Storage.findAllPojos() and findAllPojosFromCategory(). Reviewed-by: neugens Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2012-September/003184.html
author Roman Kennke <rkennke@redhat.com>
date Thu, 13 Sep 2012 17:13:25 +0200
parents 5cd4aaf85d02
children b34112e37bf2
files common/core/src/main/java/com/redhat/thermostat/common/dao/AgentInfoDAOImpl.java common/core/src/main/java/com/redhat/thermostat/common/dao/BackendInfoDAOImpl.java common/core/src/main/java/com/redhat/thermostat/common/dao/CpuStatConverter.java common/core/src/main/java/com/redhat/thermostat/common/dao/CpuStatDAOImpl.java common/core/src/main/java/com/redhat/thermostat/common/dao/HeapDAOImpl.java common/core/src/main/java/com/redhat/thermostat/common/dao/HostInfoDAOImpl.java common/core/src/main/java/com/redhat/thermostat/common/dao/HostLatestPojoListGetter.java common/core/src/main/java/com/redhat/thermostat/common/dao/MemoryStatConverter.java common/core/src/main/java/com/redhat/thermostat/common/dao/MemoryStatDAOImpl.java common/core/src/main/java/com/redhat/thermostat/common/dao/NetworkInterfaceInfoConverter.java common/core/src/main/java/com/redhat/thermostat/common/dao/NetworkInterfaceInfoDAOImpl.java common/core/src/main/java/com/redhat/thermostat/common/dao/VmClassStatConverter.java common/core/src/main/java/com/redhat/thermostat/common/dao/VmClassStatDAOImpl.java common/core/src/main/java/com/redhat/thermostat/common/dao/VmCpuStatConverter.java common/core/src/main/java/com/redhat/thermostat/common/dao/VmCpuStatDAOImpl.java common/core/src/main/java/com/redhat/thermostat/common/dao/VmGcStatConverter.java common/core/src/main/java/com/redhat/thermostat/common/dao/VmGcStatDAOImpl.java common/core/src/main/java/com/redhat/thermostat/common/dao/VmInfoDAOImpl.java common/core/src/main/java/com/redhat/thermostat/common/dao/VmLatestPojoListGetter.java common/core/src/main/java/com/redhat/thermostat/common/dao/VmMemoryStatDAOImpl.java common/core/src/main/java/com/redhat/thermostat/common/model/CpuStat.java common/core/src/main/java/com/redhat/thermostat/common/model/HostInfo.java common/core/src/main/java/com/redhat/thermostat/common/model/VmClassStat.java common/core/src/main/java/com/redhat/thermostat/common/model/VmInfo.java common/core/src/main/java/com/redhat/thermostat/common/storage/ChunkToPojoConverter.java common/core/src/main/java/com/redhat/thermostat/common/storage/Cursor.java common/core/src/main/java/com/redhat/thermostat/common/storage/MongoCursor.java common/core/src/main/java/com/redhat/thermostat/common/storage/MongoStorage.java common/core/src/main/java/com/redhat/thermostat/common/storage/Storage.java common/core/src/test/java/com/redhat/thermostat/common/dao/AgentInfoDAOTest.java common/core/src/test/java/com/redhat/thermostat/common/dao/BackendInfoDAOTest.java common/core/src/test/java/com/redhat/thermostat/common/dao/CpuStatConverterTest.java common/core/src/test/java/com/redhat/thermostat/common/dao/CpuStatDAOTest.java common/core/src/test/java/com/redhat/thermostat/common/dao/HeapDAOTest.java common/core/src/test/java/com/redhat/thermostat/common/dao/HostInfoDAOTest.java common/core/src/test/java/com/redhat/thermostat/common/dao/HostLatestPojoListGetterTest.java common/core/src/test/java/com/redhat/thermostat/common/dao/MemoryStatConverterTest.java common/core/src/test/java/com/redhat/thermostat/common/dao/MemoryStatDAOTest.java common/core/src/test/java/com/redhat/thermostat/common/dao/NetworkInterfaceInfoConverterTest.java common/core/src/test/java/com/redhat/thermostat/common/dao/NetworkInterfaceInfoDAOTest.java common/core/src/test/java/com/redhat/thermostat/common/dao/VmClassStatConverterTest.java common/core/src/test/java/com/redhat/thermostat/common/dao/VmClassStatDAOTest.java common/core/src/test/java/com/redhat/thermostat/common/dao/VmCpuStatConverterTest.java common/core/src/test/java/com/redhat/thermostat/common/dao/VmCpuStatDAOTest.java common/core/src/test/java/com/redhat/thermostat/common/dao/VmGcStatConverterTest.java common/core/src/test/java/com/redhat/thermostat/common/dao/VmGcStatDAOTest.java common/core/src/test/java/com/redhat/thermostat/common/dao/VmInfoDAOTest.java common/core/src/test/java/com/redhat/thermostat/common/dao/VmLatestPojoListGetterTest.java common/core/src/test/java/com/redhat/thermostat/common/dao/VmMemoryStatDAOTest.java common/core/src/test/java/com/redhat/thermostat/common/storage/MongoCursorTest.java common/core/src/test/java/com/redhat/thermostat/common/storage/MongoStorageTest.java thread/collector/src/main/java/com/redhat/thermostat/thread/dao/impl/ThreadDaoImpl.java
diffstat 52 files changed, 585 insertions(+), 1368 deletions(-) [+]
line wrap: on
line diff
--- a/common/core/src/main/java/com/redhat/thermostat/common/dao/AgentInfoDAOImpl.java	Tue Sep 11 22:59:49 2012 +0200
+++ b/common/core/src/main/java/com/redhat/thermostat/common/dao/AgentInfoDAOImpl.java	Thu Sep 13 17:13:25 2012 +0200
@@ -64,13 +64,13 @@
 
     @Override
     public List<AgentInformation> getAllAgentInformation() {
-        Cursor agentCursor = storage.findAllFromCategory(CATEGORY);
+        Cursor<AgentInformation> agentCursor = storage.findAllPojosFromCategory(CATEGORY, AgentInformation.class);
 
         List<AgentInformation> results = new ArrayList<>();
 
         while (agentCursor.hasNext()) {
-            Chunk agentChunk = agentCursor.next();
-            results.add(converter.fromChunk(agentChunk));
+            AgentInformation agentInfo = agentCursor.next();
+            results.add(agentInfo);
         }
         return results;
     }
@@ -81,13 +81,13 @@
                 .from(CATEGORY)
                 .where(AgentInfoDAO.ALIVE_KEY, Criteria.EQUALS, true);
 
-        Cursor agentCursor = storage.findAll(query);
+        Cursor<AgentInformation> agentCursor = storage.findAllPojos(query, AgentInformation.class);
 
         List<AgentInformation> results = new ArrayList<>();
 
         while (agentCursor.hasNext()) {
-            Chunk agentChunk = agentCursor.next();
-            results.add(converter.fromChunk(agentChunk));
+            AgentInformation agentInfo = agentCursor.next();
+            results.add(agentInfo);
         }
         return results;
     }
@@ -110,7 +110,6 @@
     public void removeAgentInformation(AgentInformation agentInfo) {
         Chunk chunk = new Chunk(CATEGORY, true);
         chunk.put(Key.AGENT_ID, agentInfo.getAgentId());
-
         storage.removeChunk(chunk);
     }
 
--- a/common/core/src/main/java/com/redhat/thermostat/common/dao/BackendInfoDAOImpl.java	Tue Sep 11 22:59:49 2012 +0200
+++ b/common/core/src/main/java/com/redhat/thermostat/common/dao/BackendInfoDAOImpl.java	Thu Sep 13 17:13:25 2012 +0200
@@ -64,10 +64,10 @@
                 .where(Key.AGENT_ID, Criteria.EQUALS, host.getAgentId());
 
         List<BackendInformation> results = new ArrayList<>();
-        Cursor cursor = storage.findAll(query);
+        Cursor<BackendInformation> cursor = storage.findAllPojos(query, BackendInformation.class);
         while (cursor.hasNext()) {
-            Chunk backendInfoPart = cursor.next();
-            results.add(converter.fromChunk(backendInfoPart));
+            BackendInformation backendInfo = cursor.next();
+            results.add(backendInfo);
         }
         return results;
     }
--- a/common/core/src/main/java/com/redhat/thermostat/common/dao/CpuStatConverter.java	Tue Sep 11 22:59:49 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +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.List;
-
-import com.redhat.thermostat.common.model.CpuStat;
-import com.redhat.thermostat.common.storage.Chunk;
-import com.redhat.thermostat.common.storage.Key;
-
-public class CpuStatConverter implements Converter<CpuStat> {
-
-    @Override
-    public Chunk toChunk(CpuStat cpuStat) {
-        Chunk chunk = new Chunk(CpuStatDAO.cpuStatCategory, false);
-        chunk.put(Key.TIMESTAMP, cpuStat.getTimeStamp());
-        List<Double> objectArray = cpuStat.getPerProcessorUsage();
-        chunk.put(CpuStatDAO.cpuLoadKey, objectArray);
-        return chunk;
-    }
-
-    @Override
-    public CpuStat fromChunk(Chunk chunk) {
-        long timestamp = chunk.get(Key.TIMESTAMP);
-        List<Double> loads = chunk.get(CpuStatDAO.cpuLoadKey);
-        return new CpuStat(timestamp, loads);
-    }
-}
--- a/common/core/src/main/java/com/redhat/thermostat/common/dao/CpuStatDAOImpl.java	Tue Sep 11 22:59:49 2012 +0200
+++ b/common/core/src/main/java/com/redhat/thermostat/common/dao/CpuStatDAOImpl.java	Thu Sep 13 17:13:25 2012 +0200
@@ -47,8 +47,6 @@
 
     private Storage storage;
 
-    private Converter<CpuStat> converter = new CpuStatConverter();;
-
     private Map<HostRef, HostLatestPojoListGetter<CpuStat>> getters = new HashMap<>();
 
     CpuStatDAOImpl(Storage storage) {
@@ -59,7 +57,7 @@
     public List<CpuStat> getLatestCpuStats(HostRef ref) {
         HostLatestPojoListGetter<CpuStat> getter = getters.get(ref);
         if (getter == null) {
-            getter = new HostLatestPojoListGetter<CpuStat>(storage, cpuStatCategory, converter, ref);
+            getter = new HostLatestPojoListGetter<CpuStat>(storage, cpuStatCategory, ref, CpuStat.class);
             getters.put(ref, getter);
         }
         return getter.getLatest();
--- a/common/core/src/main/java/com/redhat/thermostat/common/dao/HeapDAOImpl.java	Tue Sep 11 22:59:49 2012 +0200
+++ b/common/core/src/main/java/com/redhat/thermostat/common/dao/HeapDAOImpl.java	Thu Sep 13 17:13:25 2012 +0200
@@ -52,7 +52,6 @@
 import com.redhat.thermostat.common.heap.HeapDump;
 import com.redhat.thermostat.common.heap.ObjectHistogram;
 import com.redhat.thermostat.common.model.HeapInfo;
-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.Query;
@@ -108,25 +107,14 @@
                 .from(heapInfoCategory)
                 .where(Key.AGENT_ID, Criteria.EQUALS, vm.getAgent().getAgentId())
                 .where(Key.VM_ID, Criteria.EQUALS, vm.getId());
-        Cursor cursor = storage.findAll(query);
+        Cursor<HeapInfo> cursor = storage.findAllPojos(query, HeapInfo.class);
         Collection<HeapInfo> heapInfos = new ArrayList<>();
         while (cursor.hasNext()) {
-            heapInfos.add(convertChunkToHeapInfo(vm, cursor.next()));
+            heapInfos.add(cursor.next());
         }
         return heapInfos;
     }
 
-    private HeapInfo convertChunkToHeapInfo(VmRef vm, Chunk chunk) {
-        int vmId = chunk.get(Key.VM_ID);
-        String agentId = chunk.get(Key.AGENT_ID);
-        HeapInfo info = new HeapInfo(vmId, chunk.get(Key.TIMESTAMP));
-        info.setAgentId(agentId);
-        info.setHeapId(chunk.get(HeapDAO.heapIdKey));
-        info.setHeapDumpId(chunk.get(HeapDAO.heapDumpIdKey));
-        info.setHistogramId(chunk.get(HeapDAO.histogramIdKey));
-        return info;
-    }
-
     @Override
     public InputStream getHeapDumpData(HeapInfo heapInfo) {
         return storage.loadFile(heapInfo.getHeapDumpId());
--- a/common/core/src/main/java/com/redhat/thermostat/common/dao/HostInfoDAOImpl.java	Tue Sep 11 22:59:49 2012 +0200
+++ b/common/core/src/main/java/com/redhat/thermostat/common/dao/HostInfoDAOImpl.java	Thu Sep 13 17:13:25 2012 +0200
@@ -42,12 +42,11 @@
 
 import com.redhat.thermostat.common.model.AgentInformation;
 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.Query;
+import com.redhat.thermostat.common.storage.Query.Criteria;
 import com.redhat.thermostat.common.storage.Storage;
-import com.redhat.thermostat.common.storage.Query.Criteria;
 
 class HostInfoDAOImpl implements HostInfoDAO {
     private Storage storage;
@@ -98,11 +97,11 @@
     private Collection<HostRef> getHosts(Query filter) {
         Collection<HostRef> hosts = new ArrayList<HostRef>();
         
-        Cursor hostsCursor = storage.findAll(filter);
+        Cursor<HostInfo> hostsCursor = storage.findAllPojos(filter, HostInfo.class);
         while(hostsCursor.hasNext()) {
-            Chunk hostChunk = hostsCursor.next();
-            String agentId = hostChunk.get(Key.AGENT_ID);
-            String hostName = hostChunk.get(hostNameKey);
+            HostInfo host = hostsCursor.next();
+            String agentId = host.getAgentId();
+            String hostName = host.getHostname();
             hosts.add(new HostRef(agentId, hostName));
         }
         return hosts;
--- a/common/core/src/main/java/com/redhat/thermostat/common/dao/HostLatestPojoListGetter.java	Tue Sep 11 22:59:49 2012 +0200
+++ b/common/core/src/main/java/com/redhat/thermostat/common/dao/HostLatestPojoListGetter.java	Thu Sep 13 17:13:25 2012 +0200
@@ -43,32 +43,30 @@
 
 import com.redhat.thermostat.common.model.TimeStampedPojo;
 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.Cursor.SortDirection;
 import com.redhat.thermostat.common.storage.Key;
 import com.redhat.thermostat.common.storage.Query;
+import com.redhat.thermostat.common.storage.Query.Criteria;
 import com.redhat.thermostat.common.storage.Storage;
-import com.redhat.thermostat.common.storage.Cursor.SortDirection;
-import com.redhat.thermostat.common.storage.Query.Criteria;
 
 class HostLatestPojoListGetter<T extends TimeStampedPojo> implements LatestPojoListGetter<T> {
 
     private Storage storage;
     private Category cat;
-    private Converter<T> converter;
     private HostRef ref;
-
+    private Class<T> resultClass;
     private Map<HostRef, Long> lastUpdateTimes = new HashMap<>();
 
-    HostLatestPojoListGetter(Storage storage, Category cat, Converter<T> converter, HostRef ref) {
-        this(storage, cat, converter, ref, 0);
+    HostLatestPojoListGetter(Storage storage, Category cat, HostRef ref, Class<T> resultClass) {
+        this(storage, cat, ref, resultClass, 0);
     }
 
-    HostLatestPojoListGetter(Storage storage, Category cat, Converter<T> converter, HostRef ref, long since) {
+    HostLatestPojoListGetter(Storage storage, Category cat, HostRef ref, Class<T> resultClass, long since) {
         this.storage = storage;
         this.cat = cat;
-        this.converter = converter;
         this.ref = ref;
+        this.resultClass = resultClass;
         if (since > 0) {
             lastUpdateTimes.put(ref, since);
         }
@@ -84,12 +82,11 @@
         // TODO if multiple threads will be using this utility class, there may be some issues
         // with the updateTimes
         Long lastUpdate = lastUpdateTimes.get(ref);
-        Cursor cursor = storage.findAll(query);
-        cursor.sort(Key.TIMESTAMP, SortDirection.DESCENDING);
+        Cursor<T> cursor = storage.findAllPojos(query, resultClass);
+        cursor = cursor.sort(Key.TIMESTAMP, SortDirection.DESCENDING);
         List<T> result = new ArrayList<>();
         while (cursor.hasNext()) {
-            Chunk chunk = cursor.next();
-            T pojo = converter.fromChunk(chunk);
+            T pojo = cursor.next();
             result.add(pojo);
             lastUpdateTimes.put(ref, Math.max(pojo.getTimeStamp(), lastUpdate));
         }
--- a/common/core/src/main/java/com/redhat/thermostat/common/dao/MemoryStatConverter.java	Tue Sep 11 22:59:49 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +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 com.redhat.thermostat.common.model.MemoryStat;
-import com.redhat.thermostat.common.storage.Chunk;
-import com.redhat.thermostat.common.storage.Key;
-
-public class MemoryStatConverter implements Converter<MemoryStat> {
-
-    @Override
-    public Chunk toChunk(MemoryStat mem) {
-        Chunk chunk = new Chunk(MemoryStatDAO.memoryStatCategory, false);
-        chunk.put(Key.TIMESTAMP, mem.getTimeStamp());
-        chunk.put(MemoryStatDAO.memoryTotalKey, mem.getTotal());
-        chunk.put(MemoryStatDAO.memoryFreeKey, mem.getFree());
-        chunk.put(MemoryStatDAO.memoryBuffersKey, mem.getBuffers());
-        chunk.put(MemoryStatDAO.memoryCachedKey, mem.getCached());
-        chunk.put(MemoryStatDAO.memorySwapTotalKey, mem.getSwapTotal());
-        chunk.put(MemoryStatDAO.memorySwapFreeKey, mem.getSwapFree());
-        chunk.put(MemoryStatDAO.memoryCommitLimitKey, mem.getCommitLimit());
-        return chunk;
-    }
-
-    @Override
-    public MemoryStat fromChunk(Chunk chunk) {
-        long timestamp = chunk.get(Key.TIMESTAMP);
-        long total = chunk.get(MemoryStatDAO.memoryTotalKey);
-        long free = chunk.get(MemoryStatDAO.memoryFreeKey);
-        long buffers = chunk.get(MemoryStatDAO.memoryBuffersKey);
-        long cached = chunk.get(MemoryStatDAO.memoryCachedKey);
-        long swapTotal = chunk.get(MemoryStatDAO.memorySwapTotalKey);
-        long swapFree = chunk.get(MemoryStatDAO.memorySwapFreeKey);
-        long commitLimit = chunk.get(MemoryStatDAO.memoryCommitLimitKey);
-
-        return new MemoryStat(timestamp, total, free, buffers, cached, swapTotal, swapFree, commitLimit);
-    }
-}
--- a/common/core/src/main/java/com/redhat/thermostat/common/dao/MemoryStatDAOImpl.java	Tue Sep 11 22:59:49 2012 +0200
+++ b/common/core/src/main/java/com/redhat/thermostat/common/dao/MemoryStatDAOImpl.java	Thu Sep 13 17:13:25 2012 +0200
@@ -47,8 +47,6 @@
 
     private Storage storage;
 
-    private Converter<MemoryStat> converter = new MemoryStatConverter();
-
     private Map<HostRef, HostLatestPojoListGetter<MemoryStat>> getters = new HashMap<>();
 
     MemoryStatDAOImpl(Storage storage) {
@@ -59,7 +57,7 @@
     public List<MemoryStat> getLatestMemoryStats(HostRef ref) {
         HostLatestPojoListGetter<MemoryStat> getter = getters.get(ref);
         if (getter == null) {
-            getter = new HostLatestPojoListGetter<MemoryStat>(storage, memoryStatCategory, converter, ref);
+            getter = new HostLatestPojoListGetter<MemoryStat>(storage, memoryStatCategory, ref, MemoryStat.class);
             getters.put(ref, getter);
         }
         return getter.getLatest();
--- a/common/core/src/main/java/com/redhat/thermostat/common/dao/NetworkInterfaceInfoConverter.java	Tue Sep 11 22:59:49 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +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 com.redhat.thermostat.common.model.NetworkInterfaceInfo;
-import com.redhat.thermostat.common.storage.Chunk;
-
-public class NetworkInterfaceInfoConverter implements Converter<NetworkInterfaceInfo> {
-
-    @Override
-    public Chunk toChunk(NetworkInterfaceInfo info) {
-        Chunk chunk = new Chunk(NetworkInterfaceInfoDAO.networkInfoCategory, true);
-        chunk.put(NetworkInterfaceInfoDAO.ifaceKey, info.getInterfaceName());
-        String ip4 = info.getIp4Addr();
-        if (ip4 != null) {
-            chunk.put(NetworkInterfaceInfoDAO.ip4AddrKey, ip4);
-        }
-        String ip6 = info.getIp6Addr();
-        if (ip6 != null) {
-            chunk.put(NetworkInterfaceInfoDAO.ip6AddrKey, ip6);
-        }
-        return chunk;
-    }
-
-    @Override
-    public NetworkInterfaceInfo fromChunk(Chunk chunk) {
-        NetworkInterfaceInfo info = new NetworkInterfaceInfo(chunk.get(NetworkInterfaceInfoDAO.ifaceKey));
-        info.setIp4Addr(chunk.get(NetworkInterfaceInfoDAO.ip4AddrKey));
-        info.setIp6Addr(chunk.get(NetworkInterfaceInfoDAO.ip6AddrKey));
-        return info;
-    }
-}
--- a/common/core/src/main/java/com/redhat/thermostat/common/dao/NetworkInterfaceInfoDAOImpl.java	Tue Sep 11 22:59:49 2012 +0200
+++ b/common/core/src/main/java/com/redhat/thermostat/common/dao/NetworkInterfaceInfoDAOImpl.java	Thu Sep 13 17:13:25 2012 +0200
@@ -40,21 +40,18 @@
 import java.util.List;
 
 import com.redhat.thermostat.common.model.NetworkInterfaceInfo;
-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.Query;
+import com.redhat.thermostat.common.storage.Query.Criteria;
 import com.redhat.thermostat.common.storage.Storage;
-import com.redhat.thermostat.common.storage.Query.Criteria;
 
 class NetworkInterfaceInfoDAOImpl implements NetworkInterfaceInfoDAO {
 
     private Storage storage;
-    private NetworkInterfaceInfoConverter converter;
 
     NetworkInterfaceInfoDAOImpl(Storage storage) {
         this.storage = storage;
-        converter = new NetworkInterfaceInfoConverter();
     }
 
     @Override
@@ -63,11 +60,10 @@
                 .from(networkInfoCategory)
                 .where(Key.AGENT_ID, Criteria.EQUALS, ref.getAgentId());
 
-        Cursor cursor = storage.findAll(allHostNetworkInterfaces);
+        Cursor<NetworkInterfaceInfo> cursor = storage.findAllPojos(allHostNetworkInterfaces, NetworkInterfaceInfo.class);
         List<NetworkInterfaceInfo> result = new ArrayList<>();
         while (cursor.hasNext()) {
-            Chunk chunk = cursor.next();
-            NetworkInterfaceInfo stat = converter.fromChunk(chunk);
+            NetworkInterfaceInfo stat = cursor.next();
             result.add(stat);
         }
         return result;
--- a/common/core/src/main/java/com/redhat/thermostat/common/dao/VmClassStatConverter.java	Tue Sep 11 22:59:49 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +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 com.redhat.thermostat.common.model.VmClassStat;
-import com.redhat.thermostat.common.storage.Chunk;
-import com.redhat.thermostat.common.storage.Key;
-
-public class VmClassStatConverter implements Converter<VmClassStat> {
-
-    @Override
-    public Chunk toChunk(VmClassStat vmClassStat) {
-        Chunk chunk = new Chunk(VmClassStatDAO.vmClassStatsCategory, false);
-        chunk.put(Key.VM_ID, vmClassStat.getVmId());
-        chunk.put(Key.TIMESTAMP, vmClassStat.getTimeStamp());
-        chunk.put(VmClassStatDAO.loadedClassesKey, vmClassStat.getLoadedClasses());
-        return chunk;
-    }
-
-    @Override
-    public VmClassStat fromChunk(Chunk chunk) {
-        long timestamp = chunk.get(Key.TIMESTAMP);
-        long loadedClasses = chunk.get(VmClassStatDAO.loadedClassesKey);
-        int vmId = chunk.get(Key.VM_ID);
-        return new VmClassStat(vmId, timestamp, loadedClasses);
-    }
-}
--- a/common/core/src/main/java/com/redhat/thermostat/common/dao/VmClassStatDAOImpl.java	Tue Sep 11 22:59:49 2012 +0200
+++ b/common/core/src/main/java/com/redhat/thermostat/common/dao/VmClassStatDAOImpl.java	Thu Sep 13 17:13:25 2012 +0200
@@ -47,8 +47,6 @@
 
     private Storage storage;
 
-    private Converter<VmClassStat> converter = new VmClassStatConverter();
-
     private Map<VmRef, VmLatestPojoListGetter<VmClassStat>> getters = new HashMap<>();
 
     VmClassStatDAOImpl(Storage storage) {
@@ -59,7 +57,7 @@
     public List<VmClassStat> getLatestClassStats(VmRef ref) {
         VmLatestPojoListGetter<VmClassStat> getter = getters.get(ref);
         if (getter == null) {
-            getter = new VmLatestPojoListGetter<VmClassStat>(storage, vmClassStatsCategory, converter, ref);
+            getter = new VmLatestPojoListGetter<VmClassStat>(storage, vmClassStatsCategory, ref, VmClassStat.class);
             getters.put(ref, getter);
         }
         return getter.getLatest();
--- a/common/core/src/main/java/com/redhat/thermostat/common/dao/VmCpuStatConverter.java	Tue Sep 11 22:59:49 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +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 com.redhat.thermostat.common.model.VmCpuStat;
-import com.redhat.thermostat.common.storage.Chunk;
-import com.redhat.thermostat.common.storage.Key;
-
-public class VmCpuStatConverter implements Converter<VmCpuStat> {
-
-    @Override
-    public Chunk toChunk(VmCpuStat vmCpuStat) {
-        Chunk chunk = new Chunk(VmCpuStatDAO.vmCpuStatCategory, false);
-        chunk.put(Key.TIMESTAMP, vmCpuStat.getTimeStamp());
-        chunk.put(Key.VM_ID, vmCpuStat.getVmId());
-        chunk.put(VmCpuStatDAO.vmCpuLoadKey, vmCpuStat.getCpuLoad());
-        return chunk;
-    }
-
-    @Override
-    public VmCpuStat fromChunk(Chunk chunk) {
-        long timestamp = chunk.get(Key.TIMESTAMP);
-        int vmId = chunk.get(Key.VM_ID);
-        double processorUsage = chunk.get(VmCpuStatDAO.vmCpuLoadKey);
-        return new VmCpuStat(timestamp, vmId, processorUsage);
-    }
-
-}
--- a/common/core/src/main/java/com/redhat/thermostat/common/dao/VmCpuStatDAOImpl.java	Tue Sep 11 22:59:49 2012 +0200
+++ b/common/core/src/main/java/com/redhat/thermostat/common/dao/VmCpuStatDAOImpl.java	Thu Sep 13 17:13:25 2012 +0200
@@ -47,8 +47,6 @@
 
     private final Storage storage;
 
-    private Converter<VmCpuStat> converter = new VmCpuStatConverter();
-
     private Map<VmRef, VmLatestPojoListGetter<VmCpuStat>> getters = new HashMap<>();
 
     VmCpuStatDAOImpl(Storage storage) {
@@ -59,7 +57,7 @@
     public List<VmCpuStat> getLatestVmCpuStats(VmRef ref) {
         VmLatestPojoListGetter<VmCpuStat> getter = getters.get(ref);
         if (getter == null) {
-            getter = new VmLatestPojoListGetter<VmCpuStat>(storage, vmCpuStatCategory, converter, ref);
+            getter = new VmLatestPojoListGetter<VmCpuStat>(storage, vmCpuStatCategory, ref, VmCpuStat.class);
             getters.put(ref, getter);
         }
         return getter.getLatest();
--- a/common/core/src/main/java/com/redhat/thermostat/common/dao/VmGcStatConverter.java	Tue Sep 11 22:59:49 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +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 com.redhat.thermostat.common.model.VmGcStat;
-import com.redhat.thermostat.common.storage.Chunk;
-import com.redhat.thermostat.common.storage.Key;
-
-public class VmGcStatConverter implements Converter<VmGcStat> {
-
-    @Override
-    public Chunk toChunk(VmGcStat vmGcStat) {
-        Chunk chunk = new Chunk(VmGcStatDAO.vmGcStatCategory, false);
-
-        chunk.put(Key.VM_ID, vmGcStat.getVmId());
-        chunk.put(Key.TIMESTAMP, vmGcStat.getTimeStamp());
-        chunk.put(VmGcStatDAO.collectorKey, vmGcStat.getCollectorName());
-        chunk.put(VmGcStatDAO.runCountKey, vmGcStat.getRunCount());
-        chunk.put(VmGcStatDAO.wallTimeKey, vmGcStat.getWallTime());
-
-        return chunk;
-    }
-
-    @Override
-    public VmGcStat fromChunk(Chunk chunk) {
-        int vmId = chunk.get(Key.VM_ID);
-        long timestamp = chunk.get(Key.TIMESTAMP);
-        String collectorName = chunk.get(VmGcStatDAO.collectorKey);
-        long runCount = chunk.get(VmGcStatDAO.runCountKey);
-        long wallTime = chunk.get(VmGcStatDAO.wallTimeKey);
-
-        return new VmGcStat(vmId, timestamp, collectorName, runCount, wallTime);
-    }
-}
--- a/common/core/src/main/java/com/redhat/thermostat/common/dao/VmGcStatDAOImpl.java	Tue Sep 11 22:59:49 2012 +0200
+++ b/common/core/src/main/java/com/redhat/thermostat/common/dao/VmGcStatDAOImpl.java	Thu Sep 13 17:13:25 2012 +0200
@@ -47,8 +47,6 @@
 
     private Storage storage;
 
-    private Converter<VmGcStat> converter = new VmGcStatConverter();
-
     private Map<VmRef, VmLatestPojoListGetter<VmGcStat>> getters = new HashMap<>();
 
     VmGcStatDAOImpl(Storage storage) {
@@ -59,7 +57,7 @@
     public List<VmGcStat> getLatestVmGcStats(VmRef ref) {
         VmLatestPojoListGetter<VmGcStat> getter = getters.get(ref);
         if (getter == null) {
-            getter = new VmLatestPojoListGetter<VmGcStat>(storage, vmGcStatCategory, converter, ref);
+            getter = new VmLatestPojoListGetter<VmGcStat>(storage, vmGcStatCategory, ref, VmGcStat.class);
             getters.put(ref, getter);
         }
         return getter.getLatest();
--- a/common/core/src/main/java/com/redhat/thermostat/common/dao/VmInfoDAOImpl.java	Tue Sep 11 22:59:49 2012 +0200
+++ b/common/core/src/main/java/com/redhat/thermostat/common/dao/VmInfoDAOImpl.java	Thu Sep 13 17:13:25 2012 +0200
@@ -73,7 +73,7 @@
     public Collection<VmRef> getVMs(HostRef host) {
 
         Query query = buildQuery(host);
-        Cursor cursor = storage.findAll(query);
+        Cursor<VmInfo> cursor = storage.findAllPojos(query, VmInfo.class);
         return buildVMsFromQuery(cursor, host);
     }
 
@@ -84,21 +84,21 @@
         return query;
     }
 
-    private Collection<VmRef> buildVMsFromQuery(Cursor cursor, HostRef host) {
+    private Collection<VmRef> buildVMsFromQuery(Cursor<VmInfo> cursor, HostRef host) {
         List<VmRef> vmRefs = new ArrayList<VmRef>();
         while (cursor.hasNext()) {
-            Chunk vmChunk = cursor.next();
-            VmRef vm = buildVmRefFromChunk(vmChunk, host);
+            VmInfo vmInfo = cursor.next();
+            VmRef vm = buildVmRefFromChunk(vmInfo, host);
             vmRefs.add(vm);
         }
 
         return vmRefs;
     }
 
-    private VmRef buildVmRefFromChunk(Chunk vmChunk, HostRef host) {
-        Integer id = vmChunk.get(Key.VM_ID);
+    private VmRef buildVmRefFromChunk(VmInfo vmInfo, HostRef host) {
+        Integer id = vmInfo.getVmId();
         // TODO can we do better than the main class?
-        String mainClass = vmChunk.get(mainClassKey);
+        String mainClass = vmInfo.getMainClass();
         VmRef ref = new VmRef(host, id, mainClass);
         return ref;
     }
--- a/common/core/src/main/java/com/redhat/thermostat/common/dao/VmLatestPojoListGetter.java	Tue Sep 11 22:59:49 2012 +0200
+++ b/common/core/src/main/java/com/redhat/thermostat/common/dao/VmLatestPojoListGetter.java	Thu Sep 13 17:13:25 2012 +0200
@@ -47,12 +47,12 @@
 
     private VmRef vmRef;
 
-    VmLatestPojoListGetter(Storage storage, Category cat, Converter<T> converter, VmRef ref) {
-        this(storage, cat, converter, ref, 0);
+    VmLatestPojoListGetter(Storage storage, Category cat, VmRef ref, Class<T> resultClass) {
+        this(storage, cat, ref, resultClass, 0);
     }
 
-    VmLatestPojoListGetter(Storage storage, Category cat, Converter<T> converter, VmRef ref, long since) {
-        super(storage, cat, converter, ref.getAgent(), since);
+    VmLatestPojoListGetter(Storage storage, Category cat, VmRef ref, Class<T> resultClass, long since) {
+        super(storage, cat, ref.getAgent(), resultClass, since);
         vmRef = ref;
     }
 
--- a/common/core/src/main/java/com/redhat/thermostat/common/dao/VmMemoryStatDAOImpl.java	Tue Sep 11 22:59:49 2012 +0200
+++ b/common/core/src/main/java/com/redhat/thermostat/common/dao/VmMemoryStatDAOImpl.java	Thu Sep 13 17:13:25 2012 +0200
@@ -44,19 +44,17 @@
 import com.redhat.thermostat.common.storage.Cursor;
 import com.redhat.thermostat.common.storage.Key;
 import com.redhat.thermostat.common.storage.Query;
+import com.redhat.thermostat.common.storage.Query.Criteria;
 import com.redhat.thermostat.common.storage.Storage;
-import com.redhat.thermostat.common.storage.Query.Criteria;
 
 class VmMemoryStatDAOImpl implements VmMemoryStatDAO {
 
     private final Storage storage;
-    private final VmMemoryStatConverter converter;
 
     private Map<VmRef, VmLatestPojoListGetter<VmMemoryStat>> getters = new HashMap<>();
 
     VmMemoryStatDAOImpl(Storage storage) {
         this.storage = storage;
-        converter = new VmMemoryStatConverter();
     }
 
     @Override
@@ -65,9 +63,9 @@
                 .from(vmMemoryStatsCategory)
                 .where(Key.AGENT_ID, Criteria.EQUALS, ref.getAgent().getAgentId())
                 .where(Key.VM_ID, Criteria.EQUALS, ref.getId());
-        Cursor cursor = storage.findAll(query).sort(Key.TIMESTAMP, Cursor.SortDirection.DESCENDING).limit(1);
+        Cursor<VmMemoryStat> cursor = storage.findAllPojos(query, VmMemoryStat.class).sort(Key.TIMESTAMP, Cursor.SortDirection.DESCENDING).limit(1);
         if (cursor.hasNext()) {
-            return converter.fromChunk(cursor.next());
+            return cursor.next();
         }
         return null;
     }
@@ -81,7 +79,7 @@
     public List<VmMemoryStat> getLatestVmMemoryStats(VmRef ref) {
         VmLatestPojoListGetter<VmMemoryStat> getter = getters.get(ref);
         if (getter == null) {
-            getter = new VmLatestPojoListGetter<VmMemoryStat>(storage, vmMemoryStatsCategory, converter, ref);
+            getter = new VmLatestPojoListGetter<VmMemoryStat>(storage, vmMemoryStatsCategory, ref, VmMemoryStat.class);
             getters.put(ref, getter);
         }
         return getter.getLatest();
@@ -91,7 +89,7 @@
     public List<VmMemoryStat> getLatestVmMemoryStats(VmRef ref, long since) {
         VmLatestPojoListGetter<VmMemoryStat> getter = getters.get(ref);
         if (getter == null) {
-            getter = new VmLatestPojoListGetter<VmMemoryStat>(storage, vmMemoryStatsCategory, converter, ref, since);
+            getter = new VmLatestPojoListGetter<VmMemoryStat>(storage, vmMemoryStatsCategory, ref, VmMemoryStat.class, since);
             getters.put(ref, getter);
         }
         return getter.getLatest();
--- a/common/core/src/main/java/com/redhat/thermostat/common/model/CpuStat.java	Tue Sep 11 22:59:49 2012 +0200
+++ b/common/core/src/main/java/com/redhat/thermostat/common/model/CpuStat.java	Thu Sep 13 17:13:25 2012 +0200
@@ -49,6 +49,10 @@
     private long timeStamp;
     private List<Double> perProcessorUsage;
 
+    public CpuStat() {
+        this(-1, null);
+    }
+
     public CpuStat(long timestamp, List<Double> perProcessorUsage) {
         this.timeStamp = timestamp;
         this.perProcessorUsage = perProcessorUsage;
--- a/common/core/src/main/java/com/redhat/thermostat/common/model/HostInfo.java	Tue Sep 11 22:59:49 2012 +0200
+++ b/common/core/src/main/java/com/redhat/thermostat/common/model/HostInfo.java	Thu Sep 13 17:13:25 2012 +0200
@@ -42,6 +42,7 @@
 @Entity
 public class HostInfo implements Pojo {
 
+    private String agentId;
     private String hostname;
     private String osName;
     private String osKernel;
@@ -63,6 +64,16 @@
     }
 
     @Persist
+    public String getAgentId() {
+        return agentId;
+    }
+
+    @Persist
+    public void setAgentId(String agentId) {
+        this.agentId = agentId;
+    }
+
+    @Persist
     public void setHostname(String hostname) {
         this.hostname = hostname;
     }
--- a/common/core/src/main/java/com/redhat/thermostat/common/model/VmClassStat.java	Tue Sep 11 22:59:49 2012 +0200
+++ b/common/core/src/main/java/com/redhat/thermostat/common/model/VmClassStat.java	Thu Sep 13 17:13:25 2012 +0200
@@ -46,6 +46,10 @@
     private long timestamp;
     private long loadedClasses;
 
+    public VmClassStat() {
+        this(-1, -1, -1);
+    }
+
     public VmClassStat(int vmId, long timestamp, long loadedClasses) {
         this.vmId = vmId;
         this.timestamp = timestamp;
--- a/common/core/src/main/java/com/redhat/thermostat/common/model/VmInfo.java	Tue Sep 11 22:59:49 2012 +0200
+++ b/common/core/src/main/java/com/redhat/thermostat/common/model/VmInfo.java	Thu Sep 13 17:13:25 2012 +0200
@@ -92,11 +92,21 @@
     }
 
     @Persist
+    public void setVmId(int vmId) {
+        this.vmPid = vmPid;
+    }
+
+    @Persist
     public int getVmPid() {
         return vmPid;
     }
 
     @Persist
+    public void setVmPid(int vmPid) {
+        this.vmPid = vmPid;
+    }
+
+    @Persist
     public long getStartTimeStamp() {
         return startTime;
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/core/src/main/java/com/redhat/thermostat/common/storage/ChunkToPojoConverter.java	Thu Sep 13 17:13:25 2012 +0200
@@ -0,0 +1,69 @@
+/*
+ * 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.storage;
+
+import java.util.Map;
+import java.util.Set;
+
+import com.redhat.thermostat.common.dao.Converter;
+import com.redhat.thermostat.common.model.Pojo;
+
+class ChunkToPojoConverter {
+
+    static <T extends Pojo> T convertChunkToPojo(Chunk resultChunk, Class<T> resultClass, Map<Class<?>, Converter<?>> converters) {
+        try {
+            if (converters != null) {
+                Converter<?> converter = converters.get(resultClass);
+                if (converter != null) {
+                    return (T) converter.fromChunk(resultChunk);
+                }
+            }
+            Pojo pojo = resultClass.newInstance();
+            ChunkAdapter chunk = new ChunkAdapter(pojo, resultChunk.getCategory(), resultChunk.getReplace());
+            Set<Key<?>> keys = resultChunk.getKeys();
+            for (Key key : keys) {
+                if (key == null) {
+                    continue;
+                }
+                chunk.put(key, resultChunk.get(key));
+            }
+            return (T) chunk.getAdaptee();
+        } catch (InstantiationException | IllegalAccessException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
--- a/common/core/src/main/java/com/redhat/thermostat/common/storage/Cursor.java	Tue Sep 11 22:59:49 2012 +0200
+++ b/common/core/src/main/java/com/redhat/thermostat/common/storage/Cursor.java	Thu Sep 13 17:13:25 2012 +0200
@@ -36,7 +36,9 @@
 
 package com.redhat.thermostat.common.storage;
 
-public interface Cursor {
+import com.redhat.thermostat.common.model.Pojo;
+
+public interface Cursor<T extends Pojo> {
 
     public enum SortDirection {
         ASCENDING(1),
@@ -55,9 +57,9 @@
 
     boolean hasNext();
 
-    Chunk next();
+    T next();
 
-    Cursor sort(Key<?> orderBy, SortDirection direction);
+    Cursor<T> sort(Key<?> orderBy, SortDirection direction);
 
-    Cursor limit(int i);
+    Cursor<T> limit(int i);
 }
--- a/common/core/src/main/java/com/redhat/thermostat/common/storage/MongoCursor.java	Tue Sep 11 22:59:49 2012 +0200
+++ b/common/core/src/main/java/com/redhat/thermostat/common/storage/MongoCursor.java	Thu Sep 13 17:13:25 2012 +0200
@@ -36,18 +36,26 @@
 
 package com.redhat.thermostat.common.storage;
 
+import java.util.Map;
+
 import com.mongodb.BasicDBObject;
 import com.mongodb.DBCursor;
 import com.mongodb.DBObject;
+import com.redhat.thermostat.common.dao.Converter;
+import com.redhat.thermostat.common.model.Pojo;
 
-class MongoCursor implements Cursor {
+class MongoCursor<T extends Pojo> implements Cursor<T> {
 
     private DBCursor cursor;
     private Category category;
+    private Class<T> resultClass;
+    private Map<Class<?>, Converter<?>> converters;
 
-    MongoCursor(DBCursor cursor, Category category) {
+    MongoCursor(DBCursor cursor, Category category, Class<T> resultClass, Map<Class<?>, Converter<?>> converters) {
         this.cursor = cursor;
         this.category = category;
+        this.resultClass = resultClass;
+        this.converters = converters;
     }
 
     @Override
@@ -56,17 +64,18 @@
     }
 
     @Override
-    public Chunk next() {
+    public T next() {
         DBObject next = cursor.next();
         if (next == null) {
             return null;
         }
         ChunkConverter converter = new ChunkConverter();
-        return converter.dbObjectToChunk(next, category);
+        Chunk resultChunk = converter.dbObjectToChunk(next, category);
+        return ChunkToPojoConverter.convertChunkToPojo(resultChunk, resultClass, converters);
     }
 
     @Override
-    public Cursor sort(Key<?> orderBy, SortDirection direction) {
+    public Cursor<T> sort(Key<?> orderBy, SortDirection direction) {
         if (!category.getKeys().contains(orderBy)) {
             throw new IllegalArgumentException("Key not present in this Cursor's category.");
         }   /* TODO: There are other possible error conditions.  Once there is API to configure
@@ -75,13 +84,13 @@
              */
         DBObject dbOrderBy = new BasicDBObject(orderBy.getName(), direction.getValue());
         DBCursor sorted = cursor.sort(dbOrderBy);
-        return new MongoCursor(sorted, category);
+        return new MongoCursor<T>(sorted, category, resultClass, converters);
     }
 
     @Override
-    public Cursor limit(int i) {
+    public Cursor<T> limit(int i) {
         DBCursor limited = cursor.limit(i);
-        return new MongoCursor(limited, category);
+        return new MongoCursor<T>(limited, category, resultClass, converters);
     }
 
 }
--- a/common/core/src/main/java/com/redhat/thermostat/common/storage/MongoStorage.java	Tue Sep 11 22:59:49 2012 +0200
+++ b/common/core/src/main/java/com/redhat/thermostat/common/storage/MongoStorage.java	Thu Sep 13 17:13:25 2012 +0200
@@ -39,7 +39,6 @@
 import java.io.InputStream;
 import java.util.HashMap;
 import java.util.Map;
-import java.util.Set;
 import java.util.Map.Entry;
 import java.util.UUID;
 
@@ -316,34 +315,20 @@
     }
 
     @Override
-    public Cursor findAll(Query query) {
+    public <T extends Pojo> Cursor<T> findAllPojos(Query query, Class<T> resultClass) {
         MongoQuery mongoQuery =  checkAndCastQuery(query);
         DBCollection coll = getCachedCollection(mongoQuery.getCollectionName());
         DBCursor dbCursor = coll.find(mongoQuery.getGeneratedQuery());
-        return new MongoCursor(dbCursor, mongoQuery.getCategory());
+        return new MongoCursor<T>(dbCursor, mongoQuery.getCategory(), resultClass, converters);
     }
 
     @Override
-    public <T> T findPojo(Query query, Class<T> resultClass) {
+    public <T extends Pojo> T findPojo(Query query, Class<T> resultClass) {
         Chunk resultChunk = find(query);
         if (resultChunk == null) {
             return null;
         }
-        try {
-            Object pojo = resultClass.newInstance();
-            ChunkAdapter chunk = new ChunkAdapter(pojo);
-            Set<Key<?>> keys = resultChunk.getKeys();
-            for (Key key : keys) {
-                if (key == null) {
-                    System.err.println("WARNING: null key in result: " + resultChunk);
-                    continue;
-                 }
-                 chunk.put(key, resultChunk.get(key));
-            }
-            return (T) chunk.getAdaptee();
-        } catch (InstantiationException | IllegalAccessException e) {
-            throw new RuntimeException(e);
-        }
+        return ChunkToPojoConverter.convertChunkToPojo(resultChunk, resultClass, converters);
     }
 
     // TODO: Make this private, and change the testcase to test putPojo() instead.
@@ -365,10 +350,10 @@
     }
     
     @Override
-    public Cursor findAllFromCategory(Category category) {
+    public <T extends Pojo> Cursor<T> findAllPojosFromCategory(Category category, Class<T> resultClass) {
         DBCollection coll = getCachedCollection(category.getName());
         DBCursor dbCursor = coll.find();
-        return new MongoCursor(dbCursor, category);
+        return new MongoCursor<T>(dbCursor, category, resultClass, converters);
     }
 
     @Override
--- a/common/core/src/main/java/com/redhat/thermostat/common/storage/Storage.java	Tue Sep 11 22:59:49 2012 +0200
+++ b/common/core/src/main/java/com/redhat/thermostat/common/storage/Storage.java	Thu Sep 13 17:13:25 2012 +0200
@@ -69,12 +69,12 @@
      * Drop all data related to the currently running agent.
      */
     public abstract void purge();
-    
-    public abstract Cursor findAll(Query query);
+
+    public abstract <T extends Pojo> Cursor<T> findAllPojos(Query query, Class<T> resultClass);
 
-    public abstract <T> T findPojo(Query query, Class<T> resultClass);
+    public abstract <T extends Pojo> T findPojo(Query query, Class<T> resultClass);
 
-    public abstract Cursor findAllFromCategory(Category category);
+    public abstract <T extends Pojo> Cursor<T> findAllPojosFromCategory(Category category, Class<T> resultClass);
     
     public abstract long getCount(Category category);
 
--- a/common/core/src/test/java/com/redhat/thermostat/common/dao/AgentInfoDAOTest.java	Tue Sep 11 22:59:49 2012 +0200
+++ b/common/core/src/test/java/com/redhat/thermostat/common/dao/AgentInfoDAOTest.java	Thu Sep 13 17:13:25 2012 +0200
@@ -51,18 +51,19 @@
 import org.mockito.ArgumentCaptor;
 
 import com.redhat.thermostat.common.model.AgentInformation;
+import com.redhat.thermostat.common.model.Pojo;
 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.Query.Criteria;
 import com.redhat.thermostat.common.storage.Storage;
-import com.redhat.thermostat.common.storage.Query.Criteria;
 import com.redhat.thermostat.test.MockQuery;
 
 public class AgentInfoDAOTest {
 
     private AgentInformation agentInfo1;
-    private Chunk agentChunk1;
+    private AgentInformation agent1;
 
     @Before
     public void setUp() {
@@ -73,7 +74,12 @@
         agentInfo1.setStartTime(100);
         agentInfo1.setStopTime(10);
 
-        agentChunk1 = new AgentInfoConverter().toChunk(agentInfo1);
+        agent1 = new AgentInformation();
+        agent1.setAgentId("1234");
+        agent1.setAlive(true);
+        agent1.setConfigListenAddress("foobar:666");
+        agent1.setStartTime(100);
+        agent1.setStopTime(10);
     }
 
     @Test
@@ -104,12 +110,13 @@
 
     @Test
     public void verifyGetAllAgentInformationWithOneAgentInStorage() {
-        Cursor agentCursor = mock(Cursor.class);
+        @SuppressWarnings("unchecked")
+        Cursor<AgentInformation> agentCursor = mock(Cursor.class);
         when(agentCursor.hasNext()).thenReturn(true).thenReturn(false);
-        when(agentCursor.next()).thenReturn(agentChunk1).thenReturn(null);
+        when(agentCursor.next()).thenReturn(agent1).thenReturn(null);
 
         Storage storage = mock(Storage.class);
-        when(storage.findAllFromCategory(AgentInfoDAO.CATEGORY)).thenReturn(agentCursor);
+        when(storage.findAllPojosFromCategory(AgentInfoDAO.CATEGORY, AgentInformation.class)).thenReturn(agentCursor);
 
         AgentInfoDAOImpl dao = new AgentInfoDAOImpl(storage);
 
@@ -124,14 +131,15 @@
 
     @Test
     public void verifyGetAliveAgent() {
-        Cursor agentCursor = mock(Cursor.class);
+        @SuppressWarnings("unchecked")
+        Cursor<AgentInformation> agentCursor = mock(Cursor.class);
         when(agentCursor.hasNext()).thenReturn(true).thenReturn(false);
-        when(agentCursor.next()).thenReturn(agentChunk1).thenReturn(null);
+        when(agentCursor.next()).thenReturn(agent1).thenReturn(null);
 
         MockQuery query = new MockQuery();
         Storage storage = mock(Storage.class);
         when(storage.createQuery()).thenReturn(query);
-        when(storage.findAll(query)).thenReturn(agentCursor);
+        when(storage.findAllPojos(query, AgentInformation.class)).thenReturn(agentCursor);
 
         AgentInfoDAO dao = new AgentInfoDAOImpl(storage);
         List<AgentInformation> aliveAgents = dao.getAliveAgents();
@@ -199,13 +207,18 @@
 
         dao.updateAgentInformation(agentInfo1);
 
-        ArgumentCaptor<Chunk> chunkCaptor = ArgumentCaptor.forClass(Chunk.class);
-        verify(storage).updateChunk(chunkCaptor.capture());
+        ArgumentCaptor<Chunk> pojoCaptor = ArgumentCaptor.forClass(Chunk.class);
+        verify(storage).updateChunk(pojoCaptor.capture());
+
+        Chunk updatedValue = pojoCaptor.getValue();
 
-        Chunk updatedChunk = chunkCaptor.getValue();
-        Chunk expectedChunk = agentChunk1;
-
-        assertEquals(expectedChunk, updatedChunk);
+        Chunk expected = new Chunk(AgentInfoDAO.CATEGORY, true);
+        expected.put(Key.AGENT_ID, "1234");
+        expected.put(AgentInfoDAO.ALIVE_KEY, true);
+        expected.put(AgentInfoDAO.CONFIG_LISTEN_ADDRESS, "foobar:666");
+        expected.put(AgentInfoDAO.START_TIME_KEY, 100L);
+        expected.put(AgentInfoDAO.STOP_TIME_KEY, 10L);
+        assertEquals(expected, updatedValue);
     }
 
     @Test
--- a/common/core/src/test/java/com/redhat/thermostat/common/dao/BackendInfoDAOTest.java	Tue Sep 11 22:59:49 2012 +0200
+++ b/common/core/src/test/java/com/redhat/thermostat/common/dao/BackendInfoDAOTest.java	Thu Sep 13 17:13:25 2012 +0200
@@ -60,13 +60,11 @@
 
 public class BackendInfoDAOTest {
 
-    private BackendInfoConverter converter;
     private BackendInformation backendInfo1;
-    private Chunk backendChunk1;
+    private BackendInformation backend1;
 
     @Before
     public void setUp() {
-        converter = new BackendInfoConverter();
 
         backendInfo1 = new BackendInformation();
 
@@ -76,7 +74,13 @@
         backendInfo1.setObserveNewJvm(true);
         backendInfo1.setPids(Arrays.asList(new Integer[] { -1, 0, 1}));
 
-        backendChunk1 = converter.toChunk(backendInfo1);
+        backend1 = new BackendInformation();
+        backend1.setName("backend-name");
+        backend1.setDescription("description");
+        backend1.setActive(true);
+        backend1.setObserveNewJvm(true);
+        backend1.setPids(Arrays.asList(new Integer[] { -1, 0, 1}));
+        
     }
 
     @Test
@@ -114,14 +118,15 @@
         HostRef agentref = mock(HostRef.class);
         when(agentref.getAgentId()).thenReturn(AGENT_ID);
 
-        Cursor backendCursor = mock(Cursor.class);
+        @SuppressWarnings("unchecked")
+        Cursor<BackendInformation> backendCursor = mock(Cursor.class);
         when(backendCursor.hasNext()).thenReturn(true).thenReturn(false);
-        when(backendCursor.next()).thenReturn(backendChunk1).thenReturn(null);
+        when(backendCursor.next()).thenReturn(backend1).thenReturn(null);
 
         MockQuery query = new MockQuery();
         Storage storage = mock(Storage.class);
         when(storage.createQuery()).thenReturn(query);
-        when(storage.findAll(query)).thenReturn(backendCursor);
+        when(storage.findAllPojos(query, BackendInformation.class)).thenReturn(backendCursor);
 
         BackendInfoDAO dao = new BackendInfoDAOImpl(storage);
 
@@ -141,7 +146,13 @@
 
         dao.removeBackendInformation(backendInfo1);
 
-        verify(storage).removeChunk(backendChunk1);
+        Chunk backend1 = new Chunk(BackendInfoDAO.CATEGORY, true);
+        backend1.put(BackendInfoDAO.BACKEND_NAME, "backend-name");
+        backend1.put(BackendInfoDAO.BACKEND_DESCRIPTION, "description");
+        backend1.put(BackendInfoDAO.IS_ACTIVE, true);
+        backend1.put(BackendInfoDAO.SHOULD_MONITOR_NEW_PROCESSES, true);
+        backend1.put(BackendInfoDAO.PIDS_TO_MONITOR, Arrays.asList(new Integer[] { -1, 0, 1}));
+        verify(storage).removeChunk(backend1);
     }
 
 }
--- a/common/core/src/test/java/com/redhat/thermostat/common/dao/CpuStatConverterTest.java	Tue Sep 11 22:59:49 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +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.Arrays;
-
-import org.junit.Test;
-
-import com.redhat.thermostat.common.model.CpuStat;
-import com.redhat.thermostat.common.storage.Chunk;
-import com.redhat.thermostat.common.storage.Key;
-import com.redhat.thermostat.common.utils.ArrayUtils;
-
-public class CpuStatConverterTest {
-
-    @Test
-    public void testToChunk() {
-        CpuStat stat = new CpuStat(10, ArrayUtils.toDoubleList(new double[]{ 5, 10, 15} ));
-        Chunk chunk = new CpuStatConverter().toChunk(stat);
-        assertNotNull(chunk);
-        assertEquals("cpu-stats", chunk.getCategory().getName());
-        assertEquals((Long) 10L, chunk.get(Key.TIMESTAMP));
-        double[] result = ArrayUtils.toPrimitiveDoubleArray(chunk.get(CpuStatDAO.cpuLoadKey));
-        assertArrayEquals(new double[] {5, 10, 15}, result, 0.001);
-    }
-
-    @Test
-    public void testFromChunk() {
-        Chunk chunk = new Chunk(CpuStatDAO.cpuStatCategory, false);
-        chunk.put(Key.TIMESTAMP, 10L);
-        chunk.put(CpuStatDAO.cpuLoadKey, Arrays.asList(5.0, 10.0, 15.0));
-        CpuStat stat = new CpuStatConverter().fromChunk(chunk);
-        assertNotNull(stat);
-        assertEquals(10L, stat.getTimeStamp());
-        assertArrayEquals(new double[] {5.0, 10.0, 15.0} , ArrayUtils.toPrimitiveDoubleArray(stat.getPerProcessorUsage()), 0.001);
-    }
-}
--- a/common/core/src/test/java/com/redhat/thermostat/common/dao/CpuStatDAOTest.java	Tue Sep 11 22:59:49 2012 +0200
+++ b/common/core/src/test/java/com/redhat/thermostat/common/dao/CpuStatDAOTest.java	Thu Sep 13 17:13:25 2012 +0200
@@ -41,6 +41,7 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.same;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -54,8 +55,8 @@
 
 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.Cursor.SortDirection;
 import com.redhat.thermostat.common.storage.Key;
 import com.redhat.thermostat.common.storage.Query;
 import com.redhat.thermostat.common.storage.Storage;
@@ -78,7 +79,8 @@
     @Test
     public void testGetLatestCpuStats() {
 
-        Cursor cursor = mock(Cursor.class);
+        @SuppressWarnings("unchecked")
+        Cursor<CpuStat> cursor = mock(Cursor.class);
         Storage storage = mock(Storage.class);
         MockQuery query = new MockQuery();
         HostRef hostRef = mock(HostRef.class);
@@ -86,14 +88,14 @@
 
         Double LOAD = 5.0;
         List<Double> loadList = Arrays.asList(LOAD);
-        Chunk chunk = new Chunk(CpuStatDAO.cpuStatCategory, false);
-        chunk.put(Key.TIMESTAMP, 1234L);
-        chunk.put(CpuStatDAO.cpuLoadKey, loadList);
+        CpuStat cpuStat = new CpuStat(1234L, loadList);
 
         when(cursor.hasNext()).thenReturn(true).thenReturn(false);
-        when(cursor.next()).thenReturn(chunk);
+        when(cursor.next()).thenReturn(cpuStat);
+        when(cursor.sort(any(Key.class), any(SortDirection.class))).thenReturn(cursor);
+
         when(storage.createQuery()).thenReturn(query);
-        when(storage.findAll(query)).thenReturn(cursor);
+        when(storage.findAllPojos(query, CpuStat.class)).thenReturn(cursor);
         when(hostRef.getAgentId()).thenReturn("system");
 
         List<CpuStat> cpuStats = dao.getLatestCpuStats(hostRef);
@@ -110,27 +112,28 @@
     @Test
     public void testGetLatestCpuStatsTwice() {
 
-        Cursor cursor = mock(Cursor.class);
+        @SuppressWarnings("unchecked")
+        Cursor<CpuStat> cursor = mock(Cursor.class);
         Storage storage = mock(Storage.class);
         MockQuery query = new MockQuery();
         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.cpuLoadKey, Arrays.asList(5.0));
+        CpuStat cpuStat = new CpuStat(1234L, Arrays.asList(5.0));
 
         when(cursor.hasNext()).thenReturn(true).thenReturn(false);
-        when(cursor.next()).thenReturn(chunk);
+        when(cursor.next()).thenReturn(cpuStat);
+        when(cursor.sort(any(Key.class), any(SortDirection.class))).thenReturn(cursor);
+
         when(storage.createQuery()).thenReturn(query);
-        when(storage.findAll(any(Query.class))).thenReturn(cursor);
+        when(storage.findAllPojos(any(Query.class), same(CpuStat.class))).thenReturn(cursor);
         when(hostRef.getAgentId()).thenReturn("system");
 
         dao.getLatestCpuStats(hostRef);
         dao.getLatestCpuStats(hostRef);
 
-        verify(storage, times(2)).findAll(query);
+        verify(storage, times(2)).findAllPojos(query, CpuStat.class);
 
         query.hasWhereClauseFor(Key.TIMESTAMP);
     }
--- a/common/core/src/test/java/com/redhat/thermostat/common/dao/HeapDAOTest.java	Tue Sep 11 22:59:49 2012 +0200
+++ b/common/core/src/test/java/com/redhat/thermostat/common/dao/HeapDAOTest.java	Thu Sep 13 17:13:25 2012 +0200
@@ -42,7 +42,7 @@
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
-import static org.mockito.Matchers.isA;
+import static org.mockito.Matchers.same;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
@@ -68,12 +68,11 @@
 import com.redhat.thermostat.common.heap.ObjectHistogram;
 import com.redhat.thermostat.common.model.HeapInfo;
 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.Query;
+import com.redhat.thermostat.common.storage.Query.Criteria;
 import com.redhat.thermostat.common.storage.Storage;
-import com.redhat.thermostat.common.storage.Query.Criteria;
 import com.redhat.thermostat.test.MockQuery;
 import com.sun.tools.hat.internal.model.JavaClass;
 import com.sun.tools.hat.internal.model.JavaHeapObject;
@@ -115,24 +114,21 @@
             .where(Key.AGENT_ID, Criteria.EQUALS, "123")
             .where(Key.VM_ID, Criteria.EQUALS, 234);
 
-        Cursor cursor = mock(Cursor.class);
-        Chunk info1 = new Chunk(HeapDAO.heapInfoCategory, false);
-        info1.put(Key.AGENT_ID, "123");
-        info1.put(Key.VM_ID, 234);
-        info1.put(Key.TIMESTAMP, 12345l);
-        info1.put(HeapDAO.heapDumpIdKey, "test1");
-        info1.put(HeapDAO.histogramIdKey, "histotest1");
-        
-        Chunk info2 = new Chunk(HeapDAO.heapInfoCategory, false);
-        info2.put(Key.AGENT_ID, "123");
-        info2.put(Key.VM_ID, 234);
-        info2.put(Key.TIMESTAMP, 23456l);
-        info2.put(HeapDAO.heapDumpIdKey, "test2");
-        info2.put(HeapDAO.histogramIdKey, "histotest2");
-        
+        @SuppressWarnings("unchecked")
+        Cursor<HeapInfo> cursor = mock(Cursor.class);
+        HeapInfo info1 = new HeapInfo(234, 12345L);
+        info1.setAgentId("123");
+        info1.setHeapDumpId("test1");
+        info1.setHistogramId("histotest1");
+
+        HeapInfo info2 = new HeapInfo(234, 23456L);
+        info2.setAgentId("123");
+        info2.setHeapDumpId("test2");
+        info2.setHistogramId("histotest2");
+
         when(cursor.hasNext()).thenReturn(true).thenReturn(true).thenReturn(false);
         when(cursor.next()).thenReturn(info1).thenReturn(info2).thenReturn(null);
-        when(storage.findAll(findAllQuery)).thenReturn(cursor);
+        when(storage.findAllPojos(findAllQuery, HeapInfo.class)).thenReturn(cursor);
 
         // Setup for reading heapdump data.
         when(storage.loadFile("test-heap")).thenReturn(new ByteArrayInputStream(data));
@@ -279,7 +275,7 @@
     public void testInvalidHeapId() throws IOException {
         storage = mock(Storage.class);
         when(storage.createQuery()).thenReturn(new MockQuery());
-        when(storage.findPojo(any(Query.class), any(Class.class))).thenThrow(new IllegalArgumentException("invalid ObjectId"));
+        when(storage.findPojo(any(Query.class), same(HeapInfo.class))).thenThrow(new IllegalArgumentException("invalid ObjectId"));
         dao = new HeapDAOImpl(storage);
         heapInfo = dao.getHeapInfo("some-random-heap-id");
         assertTrue(heapInfo == null);
--- a/common/core/src/test/java/com/redhat/thermostat/common/dao/HostInfoDAOTest.java	Tue Sep 11 22:59:49 2012 +0200
+++ b/common/core/src/test/java/com/redhat/thermostat/common/dao/HostInfoDAOTest.java	Thu Sep 13 17:13:25 2012 +0200
@@ -132,11 +132,11 @@
 
     private Storage setupStorageForSingleHost() {
 
-        Chunk hostConfig = new Chunk(HostInfoDAO.hostInfoCategory, false);
-        hostConfig.put(HostInfoDAO.hostNameKey, "fluffhost1");
-        hostConfig.put(Key.AGENT_ID, "123");
+        HostInfo hostConfig = new HostInfo("fluffhost1", OS_NAME, OS_KERNEL, CPU_MODEL, CPU_NUM, MEMORY_TOTAL);
+        hostConfig.setAgentId("123");
 
-        Cursor cursor = mock(Cursor.class);
+        @SuppressWarnings("unchecked")
+        Cursor<HostInfo> cursor = mock(Cursor.class);
         when(cursor.hasNext()).thenReturn(true).thenReturn(false);
         when(cursor.next()).thenReturn(hostConfig);
 
@@ -147,8 +147,8 @@
                 return new MockQuery();
             }
         });
-        when(storage.findAllFromCategory(HostInfoDAO.hostInfoCategory)).thenReturn(cursor);
-        when(storage.findAll(any(Query.class))).thenReturn(cursor);
+        when(storage.findAllPojosFromCategory(HostInfoDAO.hostInfoCategory, HostInfo.class)).thenReturn(cursor);
+        when(storage.findAllPojos(any(Query.class), same(HostInfo.class))).thenReturn(cursor);
         
         return storage;
     }
@@ -170,17 +170,16 @@
 
     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");
+        HostInfo hostConfig1 = new HostInfo("fluffhost1", OS_NAME, OS_KERNEL, CPU_MODEL, CPU_NUM, MEMORY_TOTAL);
+        hostConfig1.setAgentId("123");
+        HostInfo hostConfig2 = new HostInfo("fluffhost2", OS_NAME, OS_KERNEL, CPU_MODEL, CPU_NUM, MEMORY_TOTAL);
+        hostConfig2.setAgentId("456");
+        HostInfo hostConfig3 = new HostInfo("fluffhost3", OS_NAME, OS_KERNEL, CPU_MODEL, CPU_NUM, MEMORY_TOTAL);
+        hostConfig3.setAgentId("789");
 
-        Cursor cursor = mock(Cursor.class);
+
+        @SuppressWarnings("unchecked")
+        Cursor<HostInfo> cursor = mock(Cursor.class);
         when(cursor.hasNext()).thenReturn(true).thenReturn(true).thenReturn(true).thenReturn(false);
         when(cursor.next()).thenReturn(hostConfig1).thenReturn(hostConfig2).thenReturn(hostConfig3);
 
@@ -191,8 +190,8 @@
                 return new MockQuery();
             }
         });
-        when(storage.findAllFromCategory(HostInfoDAO.hostInfoCategory)).thenReturn(cursor);
-        when(storage.findAll(any(Query.class))).thenReturn(cursor);
+        when(storage.findAllPojosFromCategory(HostInfoDAO.hostInfoCategory, HostInfo.class)).thenReturn(cursor);
+        when(storage.findAllPojos(any(Query.class), same(HostInfo.class))).thenReturn(cursor);
         
         return storage;
     }
@@ -231,34 +230,35 @@
 
         assertEquals(1, hosts.size());
         assertTrue(hosts.contains(new HostRef("123", "fluffhost1")));
-        verify(storage, times(1)).findAll(any(Query.class));
+        verify(storage, times(1)).findAllPojos(any(Query.class), same(HostInfo.class));
     }
     
     private Pair<Storage, AgentInfoDAO> setupForSingleAliveHost() {
         
         // agents
         
-        Chunk agentConfig1 = new Chunk(AgentInfoDAO.CATEGORY, false);
-        agentConfig1.put(Key.AGENT_ID, "123");
-        agentConfig1.put(AgentInfoDAO.ALIVE_KEY, true);
-        
+        AgentInformation agentConfig1 = new AgentInformation();
+        agentConfig1.setAgentId("123");
+        agentConfig1.setAlive(true);
+
         AgentInformation agentInfo1 = new AgentInformation();
         agentInfo1.setAgentId("123");
         agentInfo1.setAlive(true);
         
         // hosts
         
-        Chunk hostConfig1 = new Chunk(HostInfoDAO.hostInfoCategory, false);
-        hostConfig1.put(HostInfoDAO.hostNameKey, "fluffhost1");
-        hostConfig1.put(Key.AGENT_ID, "123");
+        HostInfo hostConfig1 = new HostInfo();
+        hostConfig1.setHostname("fluffhost1");
+        hostConfig1.setAgentId("123");
         
-        Chunk hostConfig2 = new Chunk(HostInfoDAO.hostInfoCategory, false);
-        hostConfig2.put(HostInfoDAO.hostNameKey, "fluffhost2");
-        hostConfig2.put(Key.AGENT_ID, "456");
+        HostInfo hostConfig2 = new HostInfo();
+        hostConfig2.setHostname("fluffhost2");
+        hostConfig2.setAgentId("456");
         
         // cursor
 
-        Cursor cursor1 = mock(Cursor.class);
+        @SuppressWarnings("unchecked")
+        Cursor<HostInfo> cursor1 = mock(Cursor.class);
         when(cursor1.hasNext()).thenReturn(true).thenReturn(false);
         when(cursor1.next()).thenReturn(hostConfig1);
 
@@ -271,14 +271,14 @@
                 return new MockQuery();
             }
         });
-        when(storage.findAll(any(Query.class))).thenReturn(cursor1);
+        when(storage.findAllPojos(any(Query.class), same(HostInfo.class))).thenReturn(cursor1);
 
         AgentInfoDAO agentDao = mock(AgentInfoDAO.class);
         when(agentDao.getAliveAgents()).thenReturn(Arrays.asList(agentInfo1));
 
         return new Pair<>(storage, agentDao);
     }
-    
+
     @Test
     public void getAliveHost3() {
         Pair<Storage, AgentInfoDAO> setup = setupForAliveHost3();
@@ -293,25 +293,16 @@
         assertTrue(hosts.contains(new HostRef("123", "fluffhost1")));
         assertTrue(hosts.contains(new HostRef("456", "fluffhost2")));
         assertTrue(hosts.contains(new HostRef("678", "fluffhost3")));
-        verify(storage, times(3)).findAll(any(Query.class));
+        verify(storage, times(3)).findAllPojos(any(Query.class), same(HostInfo.class));
     }
     
     private Pair<Storage, AgentInfoDAO> setupForAliveHost3() {
         
         // agents
-        
-        Chunk agentConfig1 = new Chunk(AgentInfoDAO.CATEGORY, false);
-        agentConfig1.put(Key.AGENT_ID, "123");
-        agentConfig1.put(AgentInfoDAO.ALIVE_KEY, true);
-
         AgentInformation agentInfo1 = new AgentInformation();
         agentInfo1.setAgentId("123");
         agentInfo1.setAlive(true);
 
-        Chunk agentConfig2 = new Chunk(AgentInfoDAO.CATEGORY, false);
-        agentConfig2.put(Key.AGENT_ID, "456");
-        agentConfig2.put(AgentInfoDAO.ALIVE_KEY, true);
-
         AgentInformation agentInfo2 = new AgentInformation();
         agentInfo2.setAgentId("456");
         agentInfo2.setAlive(true);
@@ -326,30 +317,33 @@
         
         // hosts
         
-        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, "678");
-        
-        Cursor cursor1 = mock(Cursor.class);
+        HostInfo hostConfig1 = new HostInfo();
+        hostConfig1.setHostname("fluffhost1");
+        hostConfig1.setAgentId("123");
+
+        HostInfo hostConfig2 = new HostInfo();
+        hostConfig2.setHostname("fluffhost2");
+        hostConfig2.setAgentId("456");
+
+        HostInfo hostConfig3 = new HostInfo();
+        hostConfig3.setHostname("fluffhost3");
+        hostConfig3.setAgentId("678");
+
+        @SuppressWarnings("unchecked")
+        Cursor<HostInfo> cursor1 = mock(Cursor.class);
         when(cursor1.hasNext()).thenReturn(true).thenReturn(false);
         when(cursor1.next()).thenReturn(hostConfig1);
 
-        Cursor cursor2 = mock(Cursor.class);
+        @SuppressWarnings("unchecked")
+        Cursor<HostInfo> cursor2 = mock(Cursor.class);
         when(cursor2.hasNext()).thenReturn(true).thenReturn(false);
         when(cursor2.next()).thenReturn(hostConfig2);
 
-        Cursor cursor3 = mock(Cursor.class);
+        @SuppressWarnings("unchecked")
+        Cursor<HostInfo> cursor3 = mock(Cursor.class);
         when(cursor3.hasNext()).thenReturn(true).thenReturn(false);
         when(cursor3.next()).thenReturn(hostConfig3);
-        
+
         // storage
         
         Storage storage = mock(Storage.class);
@@ -359,9 +353,9 @@
                 return new MockQuery();
             }
         });
-        when(storage.findAll(any(Query.class))).thenReturn(cursor1).
-                                                thenReturn(cursor2).
-                                                thenReturn(cursor3);
+        when(storage.findAllPojos(any(Query.class), same(HostInfo.class))).thenReturn(cursor1).
+                                                                           thenReturn(cursor2).
+                                                                           thenReturn(cursor3);
         
         AgentInfoDAO agentDao = mock(AgentInfoDAO.class);
         when(agentDao.getAliveAgents()).thenReturn(Arrays.asList(agentInfo1, agentInfo2, agentInfo3));
--- a/common/core/src/test/java/com/redhat/thermostat/common/dao/HostLatestPojoListGetterTest.java	Tue Sep 11 22:59:49 2012 +0200
+++ b/common/core/src/test/java/com/redhat/thermostat/common/dao/HostLatestPojoListGetterTest.java	Thu Sep 13 17:13:25 2012 +0200
@@ -41,7 +41,8 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.isA;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.same;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -56,10 +57,10 @@
 
 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;
 import com.redhat.thermostat.common.storage.Query;
+import com.redhat.thermostat.common.storage.Cursor.SortDirection;
 import com.redhat.thermostat.common.storage.Query.Criteria;
 import com.redhat.thermostat.common.storage.Storage;
 import com.redhat.thermostat.common.utils.ArrayUtils;
@@ -90,25 +91,14 @@
     private static Double load15_3 = 13.0;
 
     private HostRef ref;
-    private Converter<CpuStat> converter;
-    private Chunk result1, result2, result3;
+    private CpuStat result1, result2, result3;
 
     @Before
     public void setUp() {
         ref = new HostRef(AGENT_ID, HOSTNAME);
-        converter = new CpuStatConverter();
-        result1 = new Chunk(cat, false);
-        result1.put(Key.AGENT_ID, AGENT_ID);
-        result1.put(Key.TIMESTAMP, t1);
-        result1.put(CpuStatDAO.cpuLoadKey, Arrays.asList(load5_1, load10_1, load15_1));
-        result2 = new Chunk(cat, false);
-        result2.put(Key.AGENT_ID, AGENT_ID);
-        result2.put(Key.TIMESTAMP, t2);
-        result2.put(CpuStatDAO.cpuLoadKey, Arrays.asList(load5_2, load10_2, load15_2));
-        result3 = new Chunk(cat, false);
-        result3.put(Key.AGENT_ID, AGENT_ID);
-        result3.put(Key.TIMESTAMP, t3);
-        result3.put(CpuStatDAO.cpuLoadKey, Arrays.asList(load5_3, load10_3, load15_3));
+        result1 = new CpuStat(t1, Arrays.asList(load5_1, load10_1, load15_1));
+        result2 = new CpuStat(t2, Arrays.asList(load5_2, load10_2, load15_2));
+        result3 = new CpuStat(t3, Arrays.asList(load5_3, load10_3, load15_3));
     }
 
     @Test
@@ -117,7 +107,7 @@
         MockQuery query = new MockQuery();
         when (storage.createQuery()).thenReturn(query);
 
-        HostLatestPojoListGetter<CpuStat> getter = new HostLatestPojoListGetter<>(storage, cat, converter, ref);
+        HostLatestPojoListGetter<CpuStat> getter = new HostLatestPojoListGetter<>(storage, cat, ref, CpuStat.class);
         query = (MockQuery) getter.buildQuery();
 
         assertNotNull(query);
@@ -133,7 +123,7 @@
         MockQuery query = new MockQuery();
         when (storage.createQuery()).thenReturn(query);
 
-        HostLatestPojoListGetter<CpuStat> getter = new HostLatestPojoListGetter<>(storage, cat, converter, ref, 123);
+        HostLatestPojoListGetter<CpuStat> getter = new HostLatestPojoListGetter<>(storage, cat, ref, CpuStat.class, 123);
         query = (MockQuery) getter.buildQuery();
 
         assertNotNull(query);
@@ -150,7 +140,7 @@
         MockQuery query = new MockQuery();
         when(storage.createQuery()).thenReturn(ignored).thenReturn(query);
 
-        HostLatestPojoListGetter<CpuStat> getter = new HostLatestPojoListGetter<>(storage, cat, converter, ref);
+        HostLatestPojoListGetter<CpuStat> getter = new HostLatestPojoListGetter<>(storage, cat, ref, CpuStat.class);
         ignored = (MockQuery) getter.buildQuery(); // Ignore first return value.
 
         query = (MockQuery) getter.buildQuery();
@@ -164,16 +154,18 @@
 
     @Test
     public void testGetLatest() {
-        Cursor cursor = mock(Cursor.class);
+        @SuppressWarnings("unchecked")
+        Cursor<CpuStat> cursor = mock(Cursor.class);
         when(cursor.hasNext()).thenReturn(true).thenReturn(true).thenReturn(false);
         when(cursor.next()).thenReturn(result1).thenReturn(result2).thenReturn(null);
+        when(cursor.sort(any(Key.class), any(SortDirection.class))).thenReturn(cursor);
 
         Storage storage = mock(Storage.class);
         Query query = new MockQuery();
         when(storage.createQuery()).thenReturn(query);
-        when(storage.findAll(query)).thenReturn(cursor);
+        when(storage.findAllPojos(query, CpuStat.class)).thenReturn(cursor);
 
-        HostLatestPojoListGetter<CpuStat> getter = new HostLatestPojoListGetter<>(storage, cat, converter, ref);
+        HostLatestPojoListGetter<CpuStat> getter = new HostLatestPojoListGetter<>(storage, cat, ref, CpuStat.class);
 
         List<CpuStat> stats = getter.getLatest();
 
@@ -189,26 +181,30 @@
 
     @Test
     public void testGetLatestMultipleCalls() {
-        Cursor cursor1 = mock(Cursor.class);
+        @SuppressWarnings("unchecked")
+        Cursor<CpuStat> cursor1 = mock(Cursor.class);
         when(cursor1.hasNext()).thenReturn(true).thenReturn(true).thenReturn(false);
         when(cursor1.next()).thenReturn(result1).thenReturn(result2).thenReturn(null);
+        when(cursor1.sort(any(Key.class), any(SortDirection.class))).thenReturn(cursor1);
 
-        Cursor cursor2 = mock(Cursor.class);
+        @SuppressWarnings("unchecked")
+        Cursor<CpuStat> cursor2 = mock(Cursor.class);
         when(cursor2.hasNext()).thenReturn(true).thenReturn(false);
         when(cursor2.next()).thenReturn(result3);
+        when(cursor2.sort(any(Key.class), any(SortDirection.class))).thenReturn(cursor2);
 
         Storage storage = mock(Storage.class);
         MockQuery firstQuery = new MockQuery();
         MockQuery secondQuery = new MockQuery();
         when(storage.createQuery()).thenReturn(firstQuery).thenReturn(secondQuery);
 
-        when(storage.findAll(isA(Query.class))).thenReturn(cursor1);
+        when(storage.findAllPojos(any(Query.class), same(CpuStat.class))).thenReturn(cursor1);
 
-        HostLatestPojoListGetter<CpuStat> getter = new HostLatestPojoListGetter<>(storage, cat, converter, ref);
+        HostLatestPojoListGetter<CpuStat> getter = new HostLatestPojoListGetter<>(storage, cat, ref, CpuStat.class);
         getter.getLatest();
         getter.getLatest();
 
-        verify(storage, times(2)).findAll(isA(Query.class));
+        verify(storage, times(2)).findAllPojos(any(Query.class), same(CpuStat.class));
 
         assertTrue(secondQuery.hasWhereClause(Key.AGENT_ID, Criteria.EQUALS, AGENT_ID));
         assertTrue(secondQuery.hasWhereClause(Key.TIMESTAMP, Criteria.GREATER_THAN, t2));
@@ -217,7 +213,6 @@
     @After
     public void tearDown() {
         ref = null;
-        converter = null;
         result1 = null;
         result2 = null;
         result3 = null;
--- a/common/core/src/test/java/com/redhat/thermostat/common/dao/MemoryStatConverterTest.java	Tue Sep 11 22:59:49 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +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 org.junit.Test;
-
-import com.redhat.thermostat.common.model.MemoryStat;
-import com.redhat.thermostat.common.storage.Chunk;
-import com.redhat.thermostat.common.storage.Key;
-
-public class MemoryStatConverterTest {
-
-    @Test
-    public void testMemoryStatToChunk() {
-        MemoryStat stat = new MemoryStat(0, 1, 2, 3, 4, 5, 6, 7);
-
-        Chunk chunk = new MemoryStatConverter().toChunk(stat);
-
-        assertEquals((Long) 0l, chunk.get(Key.TIMESTAMP));
-        assertEquals((Long) 1l, chunk.get(new Key<Long>("total", false)));
-        assertEquals((Long) 2l, chunk.get(new Key<Long>("free", false)));
-        assertEquals((Long) 3l, chunk.get(new Key<Long>("buffers", false)));
-        assertEquals((Long) 4l, chunk.get(new Key<Long>("cached", false)));
-        assertEquals((Long) 5l, chunk.get(new Key<Long>("swapTotal", false)));
-        assertEquals((Long) 6l, chunk.get(new Key<Long>("swapFree", false)));
-        assertEquals((Long) 7l, chunk.get(new Key<Long>("commitLimit", false)));
-    }
-
-    @Test
-    public void testChunkToMemoryStat() {
-        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);
-        chunk.put(MemoryStatDAO.memoryTotalKey, TOTAL);
-        chunk.put(MemoryStatDAO.memoryFreeKey, FREE);
-        chunk.put(MemoryStatDAO.memoryBuffersKey, BUFFERS);
-        chunk.put(MemoryStatDAO.memoryCachedKey, CACHED);
-        chunk.put(MemoryStatDAO.memorySwapTotalKey, SWAP_TOTAL);
-        chunk.put(MemoryStatDAO.memorySwapFreeKey, SWAP_FREE);
-        chunk.put(MemoryStatDAO.memoryCommitLimitKey, COMMIT_LIMIT);
-
-        MemoryStat stat = new MemoryStatConverter().fromChunk(chunk);
-
-        assertEquals(TIMESTAMP, stat.getTimeStamp());
-        assertEquals(TOTAL, stat.getTotal());
-        assertEquals(FREE, stat.getFree());
-        assertEquals(BUFFERS, stat.getBuffers());
-        assertEquals(CACHED, stat.getCached());
-        assertEquals(SWAP_TOTAL, stat.getSwapTotal());
-        assertEquals(SWAP_FREE, stat.getSwapFree());
-        assertEquals(COMMIT_LIMIT, stat.getCommitLimit());
-    }
-}
--- a/common/core/src/test/java/com/redhat/thermostat/common/dao/MemoryStatDAOTest.java	Tue Sep 11 22:59:49 2012 +0200
+++ b/common/core/src/test/java/com/redhat/thermostat/common/dao/MemoryStatDAOTest.java	Thu Sep 13 17:13:25 2012 +0200
@@ -40,6 +40,7 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.same;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -55,8 +56,8 @@
 
 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.Cursor.SortDirection;
 import com.redhat.thermostat.common.storage.Key;
 import com.redhat.thermostat.common.storage.Query;
 import com.redhat.thermostat.common.storage.Query.Criteria;
@@ -95,19 +96,13 @@
     @Test
     public void testGetLatestMemoryStats() {
 
-        Chunk chunk = new Chunk(MemoryStatDAO.memoryStatCategory, false);
-        chunk.put(Key.TIMESTAMP, TIMESTAMP);
-        chunk.put(MemoryStatDAO.memoryTotalKey, TOTAL);
-        chunk.put(MemoryStatDAO.memoryFreeKey, FREE);
-        chunk.put(MemoryStatDAO.memoryBuffersKey, BUFFERS);
-        chunk.put(MemoryStatDAO.memoryCachedKey, CACHED);
-        chunk.put(MemoryStatDAO.memorySwapTotalKey, SWAP_TOTAL);
-        chunk.put(MemoryStatDAO.memorySwapFreeKey, SWAP_FREE);
-        chunk.put(MemoryStatDAO.memoryCommitLimitKey, COMMIT_LIMIT);
+        MemoryStat memStat1 = new MemoryStat(TIMESTAMP, TOTAL, FREE, BUFFERS, CACHED, SWAP_TOTAL, SWAP_FREE, COMMIT_LIMIT);
 
-        Cursor cursor = mock(Cursor.class);
+        @SuppressWarnings("unchecked")
+        Cursor<MemoryStat> cursor = mock(Cursor.class);
         when(cursor.hasNext()).thenReturn(true).thenReturn(false);
-        when(cursor.next()).thenReturn(chunk);
+        when(cursor.next()).thenReturn(memStat1);
+        when(cursor.sort(any(Key.class), any(SortDirection.class))).thenReturn(cursor);
 
         Storage storage = mock(Storage.class);
         when(storage.createQuery()).then(new Answer<Query>() {
@@ -116,7 +111,7 @@
                 return new MockQuery();
             }
         });
-        when(storage.findAll(any(Query.class))).thenReturn(cursor);
+        when(storage.findAllPojos(any(Query.class), same(MemoryStat.class))).thenReturn(cursor);
 
         HostRef hostRef = mock(HostRef.class);
         when(hostRef.getAgentId()).thenReturn("system");
@@ -125,7 +120,7 @@
         List<MemoryStat> memoryStats = dao.getLatestMemoryStats(hostRef);
 
         ArgumentCaptor<MockQuery> arg = ArgumentCaptor.forClass(MockQuery.class);
-        verify(storage).findAll(arg.capture());
+        verify(storage).findAllPojos(arg.capture(), same(MemoryStat.class));
         assertFalse(arg.getValue().hasWhereClauseFor(Key.TIMESTAMP));
 
         assertEquals(1, memoryStats.size());
@@ -144,19 +139,13 @@
     @Test
     public void testGetLatestMemoryStatsTwice() {
 
-        Chunk chunk = new Chunk(MemoryStatDAO.memoryStatCategory, false);
-        chunk.put(Key.TIMESTAMP, TIMESTAMP);
-        chunk.put(MemoryStatDAO.memoryTotalKey, TOTAL);
-        chunk.put(MemoryStatDAO.memoryFreeKey, FREE);
-        chunk.put(MemoryStatDAO.memoryBuffersKey, BUFFERS);
-        chunk.put(MemoryStatDAO.memoryCachedKey, CACHED);
-        chunk.put(MemoryStatDAO.memorySwapTotalKey, SWAP_TOTAL);
-        chunk.put(MemoryStatDAO.memorySwapFreeKey, SWAP_FREE);
-        chunk.put(MemoryStatDAO.memoryCommitLimitKey, COMMIT_LIMIT);
+        MemoryStat memStat = new MemoryStat(TIMESTAMP, TOTAL, FREE, BUFFERS, CACHED, SWAP_TOTAL, SWAP_FREE, COMMIT_LIMIT);
 
-        Cursor cursor = mock(Cursor.class);
+        @SuppressWarnings("unchecked")
+        Cursor<MemoryStat> cursor = mock(Cursor.class);
         when(cursor.hasNext()).thenReturn(true).thenReturn(false);
-        when(cursor.next()).thenReturn(chunk);
+        when(cursor.next()).thenReturn(memStat);
+        when(cursor.sort(any(Key.class), any(SortDirection.class))).thenReturn(cursor);
 
         Storage storage = mock(Storage.class);
         when(storage.createQuery()).then(new Answer<Query>() {
@@ -165,7 +154,7 @@
                 return new MockQuery();
             }
         });
-        when(storage.findAll(any(Query.class))).thenReturn(cursor);
+        when(storage.findAllPojos(any(Query.class), same(MemoryStat.class))).thenReturn(cursor);
 
         HostRef hostRef = mock(HostRef.class);
         when(hostRef.getAgentId()).thenReturn("system");
@@ -175,7 +164,7 @@
         dao.getLatestMemoryStats(hostRef);
 
         ArgumentCaptor<MockQuery> arg = ArgumentCaptor.forClass(MockQuery.class);
-        verify(storage, times(2)).findAll(arg.capture());
+        verify(storage, times(2)).findAllPojos(arg.capture(), same(MemoryStat.class));
         assertTrue(arg.getValue().hasWhereClause(Key.TIMESTAMP, Criteria.GREATER_THAN, 1l));
     }
 
--- a/common/core/src/test/java/com/redhat/thermostat/common/dao/NetworkInterfaceInfoConverterTest.java	Tue Sep 11 22:59:49 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +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.assertNotNull;
-
-import org.junit.Test;
-
-import com.redhat.thermostat.common.model.NetworkInterfaceInfo;
-import com.redhat.thermostat.common.storage.Chunk;
-import com.redhat.thermostat.common.storage.Key;
-
-public class NetworkInterfaceInfoConverterTest {
-
-    @Test
-    public void testNetworkInfoToChunk() {
-        NetworkInterfaceInfo info = new NetworkInterfaceInfo("eth0");
-        info.setIp4Addr("4");
-        info.setIp6Addr("6");
-
-        Chunk chunk = new NetworkInterfaceInfoConverter().toChunk(info);
-
-        assertEquals("network-info", chunk.getCategory().getName());
-        assertEquals("eth0", chunk.get(new Key<String>("interfaceName", true)));
-        assertEquals("4", chunk.get(new Key<String>("ip4Addr", false)));
-        assertEquals("6", chunk.get(new Key<String>("ip6Addr", false)));
-
-    }
-
-    @Test
-    public void testChunkToNetworkInfo() {
-        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);
-        chunk.put(NetworkInterfaceInfoDAO.ip4AddrKey, IPV4_ADDR);
-        chunk.put(NetworkInterfaceInfoDAO.ip6AddrKey, IPV6_ADDR);
-
-        NetworkInterfaceInfo info = new NetworkInterfaceInfoConverter().fromChunk(chunk);
-        assertNotNull(info);
-        assertEquals(INTERFACE_NAME, info.getInterfaceName());
-        assertEquals(IPV4_ADDR, info.getIp4Addr());
-        assertEquals(IPV6_ADDR, info.getIp6Addr());
-    }
-
-}
--- a/common/core/src/test/java/com/redhat/thermostat/common/dao/NetworkInterfaceInfoDAOTest.java	Tue Sep 11 22:59:49 2012 +0200
+++ b/common/core/src/test/java/com/redhat/thermostat/common/dao/NetworkInterfaceInfoDAOTest.java	Thu Sep 13 17:13:25 2012 +0200
@@ -38,10 +38,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
-
-import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -50,10 +47,8 @@
 import java.util.List;
 
 import org.junit.Test;
-import org.mockito.ArgumentCaptor;
 
 import com.redhat.thermostat.common.model.NetworkInterfaceInfo;
-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;
@@ -81,19 +76,19 @@
     @Test
     public void testGetNetworkInterfaces() {
 
-        Chunk chunk = new Chunk(NetworkInterfaceInfoDAO.networkInfoCategory, false);
-        chunk.put(NetworkInterfaceInfoDAO.ifaceKey, INTERFACE_NAME);
-        chunk.put(NetworkInterfaceInfoDAO.ip4AddrKey, IPV4_ADDR);
-        chunk.put(NetworkInterfaceInfoDAO.ip6AddrKey, IPV6_ADDR);
+        NetworkInterfaceInfo niInfo = new NetworkInterfaceInfo(INTERFACE_NAME);
+        niInfo.setIp4Addr(IPV4_ADDR);
+        niInfo.setIp6Addr(IPV6_ADDR);
 
-        Cursor cursor = mock(Cursor.class);
+        @SuppressWarnings("unchecked")
+        Cursor<NetworkInterfaceInfo> cursor = mock(Cursor.class);
         when(cursor.hasNext()).thenReturn(true).thenReturn(false);
-        when(cursor.next()).thenReturn(chunk);
+        when(cursor.next()).thenReturn(niInfo);
 
         Storage storage = mock(Storage.class);
         MockQuery query = new MockQuery();
         when(storage.createQuery()).thenReturn(query);
-        when(storage.findAll(query)).thenReturn(cursor);
+        when(storage.findAllPojos(query, NetworkInterfaceInfo.class)).thenReturn(cursor);
 
         HostRef hostRef = mock(HostRef.class);
         when(hostRef.getAgentId()).thenReturn("system");
--- a/common/core/src/test/java/com/redhat/thermostat/common/dao/VmClassStatConverterTest.java	Tue Sep 11 22:59:49 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 static org.junit.Assert.assertEquals;
-
-import org.junit.Test;
-
-import com.redhat.thermostat.common.model.VmClassStat;
-import com.redhat.thermostat.common.storage.Chunk;
-import com.redhat.thermostat.common.storage.Key;
-
-public class VmClassStatConverterTest {
-
-    @Test
-    public void testVmClassStatToChunk() {
-        VmClassStat stat = new VmClassStat(123, 1234L, 12345L);
-
-        VmClassStatConverter dao = new VmClassStatConverter();
-        Chunk chunk = dao.toChunk(stat);
-
-        assertEquals("vm-class-stats", chunk.getCategory().getName());
-        assertEquals((Long) 1234L, chunk.get(Key.TIMESTAMP));
-        assertEquals((Integer) 123, chunk.get(new Key<Integer>("vmId", true)));
-        assertEquals((Long) 12345L, chunk.get(new Key<Long>("loadedClasses", false)));
-    }
-
-    @Test
-    public void testChunkToVmClassStat() {
-        Chunk chunk = new Chunk(VmClassStatDAO.vmClassStatsCategory, false);
-        chunk.put(Key.VM_ID, 123);
-        chunk.put(Key.TIMESTAMP, 1234L);
-        chunk.put(VmClassStatDAO.loadedClassesKey, 12345L);
-
-        VmClassStat stat = new VmClassStatConverter().fromChunk(chunk);
-
-        assertEquals(123, stat.getVmId());
-        assertEquals(1234L, stat.getTimeStamp());
-        assertEquals(12345L, stat.getLoadedClasses());
-    }
-}
--- a/common/core/src/test/java/com/redhat/thermostat/common/dao/VmClassStatDAOTest.java	Tue Sep 11 22:59:49 2012 +0200
+++ b/common/core/src/test/java/com/redhat/thermostat/common/dao/VmClassStatDAOTest.java	Thu Sep 13 17:13:25 2012 +0200
@@ -40,6 +40,7 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.same;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -54,10 +55,10 @@
 import org.mockito.stubbing.Answer;
 
 import com.redhat.thermostat.common.model.VmClassStat;
-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.Query;
+import com.redhat.thermostat.common.storage.Cursor.SortDirection;
 import com.redhat.thermostat.common.storage.Query.Criteria;
 import com.redhat.thermostat.common.storage.Storage;
 import com.redhat.thermostat.test.MockQuery;
@@ -83,11 +84,13 @@
     @Test
     public void testGetLatestClassStatsBasic() {
 
-        Chunk chunk = getChunk();
+        VmClassStat vmClassStat = getClassStat();
 
-        Cursor cursor = mock(Cursor.class);
+        @SuppressWarnings("unchecked")
+        Cursor<VmClassStat> cursor = mock(Cursor.class);
         when(cursor.hasNext()).thenReturn(true).thenReturn(false);
-        when(cursor.next()).thenReturn(chunk);
+        when(cursor.next()).thenReturn(vmClassStat);
+        when(cursor.sort(any(Key.class), any(SortDirection.class))).thenReturn(cursor);
 
         Storage storage = mock(Storage.class);
         when(storage.createQuery()).then(new Answer<Query>() {
@@ -96,7 +99,7 @@
                 return new MockQuery();
             }
         });
-        when(storage.findAll(any(Query.class))).thenReturn(cursor);
+        when(storage.findAllPojos(any(Query.class), same(VmClassStat.class))).thenReturn(cursor);
 
         HostRef hostRef = mock(HostRef.class);
         when(hostRef.getAgentId()).thenReturn("system");
@@ -110,7 +113,7 @@
         List<VmClassStat> vmClassStats = dao.getLatestClassStats(vmRef);
 
         ArgumentCaptor<MockQuery> arg = ArgumentCaptor.forClass(MockQuery.class);
-        verify(storage).findAll(arg.capture());
+        verify(storage).findAllPojos(arg.capture(), same(VmClassStat.class));
         assertFalse(arg.getValue().hasWhereClauseFor(Key.TIMESTAMP));
 
         assertEquals(1, vmClassStats.size());
@@ -123,11 +126,14 @@
     @Test
     public void testGetLatestClassStatsTwice() {
 
-        Chunk chunk = getChunk();
+        VmClassStat vmClassStat = getClassStat();
 
-        Cursor cursor = mock(Cursor.class);
+        @SuppressWarnings("unchecked")
+        Cursor<VmClassStat> cursor = mock(Cursor.class);
+
         when(cursor.hasNext()).thenReturn(true).thenReturn(false);
-        when(cursor.next()).thenReturn(chunk);
+        when(cursor.next()).thenReturn(vmClassStat);
+        when(cursor.sort(any(Key.class), any(SortDirection.class))).thenReturn(cursor);
 
         Storage storage = mock(Storage.class);
         when(storage.createQuery()).then(new Answer<Query>() {
@@ -136,7 +142,7 @@
                 return new MockQuery();
             }
         });
-        when(storage.findAll(any(Query.class))).thenReturn(cursor);
+        when(storage.findAllPojos(any(Query.class), same(VmClassStat.class))).thenReturn(cursor);
 
         HostRef hostRef = mock(HostRef.class);
         when(hostRef.getAgentId()).thenReturn("system");
@@ -151,16 +157,12 @@
 
         dao.getLatestClassStats(vmRef);
         ArgumentCaptor<MockQuery> arg = ArgumentCaptor.forClass(MockQuery.class);
-        verify(storage, times(2)).findAll(arg.capture());
+        verify(storage, times(2)).findAllPojos(arg.capture(), same(VmClassStat.class));
         assertTrue(arg.getValue().hasWhereClause(Key.TIMESTAMP, Criteria.GREATER_THAN, 1234l));
     }
 
-    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;
+    private VmClassStat getClassStat() {
+        return new VmClassStat(VM_ID, TIMESTAMP, LOADED_CLASSES);
     }
 
     @Test
--- a/common/core/src/test/java/com/redhat/thermostat/common/dao/VmCpuStatConverterTest.java	Tue Sep 11 22:59:49 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +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 org.junit.Test;
-
-import com.redhat.thermostat.common.model.VmCpuStat;
-import com.redhat.thermostat.common.storage.Chunk;
-import com.redhat.thermostat.common.storage.Key;
-
-public class VmCpuStatConverterTest {
-
-    final long TIMESTAMP = 12345l;
-    final int VM_ID = 678;
-    final double PROCESSOR_USAGE = 9.9;
-
-    @Test
-    public void testVmCpuStatToChunk() {
-
-        VmCpuStat vmCpuStat = new VmCpuStat(TIMESTAMP, VM_ID, PROCESSOR_USAGE);
-        Chunk chunk = new VmCpuStatConverter().toChunk(vmCpuStat);
-        assertNotNull(chunk);
-        assertEquals("vm-cpu-stats", chunk.getCategory().getName());
-        assertEquals((Long)TIMESTAMP, chunk.get(Key.TIMESTAMP));
-        assertEquals((Integer) VM_ID, chunk.get(new Key<Long>("vmId", true)));
-        assertEquals(PROCESSOR_USAGE, chunk.get(new Key<Double>("cpuLoad", false)), 0.001);
-
-    }
-
-    @Test
-    public void testChunkToVmCpuStat() {
-        Chunk chunk = new Chunk(VmCpuStatDAO.vmCpuStatCategory, false);
-        chunk.put(Key.TIMESTAMP, TIMESTAMP);
-        chunk.put(Key.VM_ID, VM_ID);
-        chunk.put(VmCpuStatDAO.vmCpuLoadKey, PROCESSOR_USAGE);
-
-        VmCpuStat stat = new VmCpuStatConverter().fromChunk(chunk);
-        assertNotNull(stat);
-        assertEquals(TIMESTAMP, stat.getTimeStamp());
-        assertEquals(VM_ID, stat.getVmId());
-        assertEquals(PROCESSOR_USAGE, stat.getCpuLoad(), 0.001);
-
-    }
-
-}
--- a/common/core/src/test/java/com/redhat/thermostat/common/dao/VmCpuStatDAOTest.java	Tue Sep 11 22:59:49 2012 +0200
+++ b/common/core/src/test/java/com/redhat/thermostat/common/dao/VmCpuStatDAOTest.java	Thu Sep 13 17:13:25 2012 +0200
@@ -38,9 +38,10 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.same;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -56,30 +57,25 @@
 import org.mockito.stubbing.Answer;
 
 import com.redhat.thermostat.common.model.VmCpuStat;
-import com.redhat.thermostat.common.storage.Chunk;
 import com.redhat.thermostat.common.storage.Cursor;
+import com.redhat.thermostat.common.storage.Cursor.SortDirection;
 import com.redhat.thermostat.common.storage.Key;
 import com.redhat.thermostat.common.storage.Query;
+import com.redhat.thermostat.common.storage.Query.Criteria;
 import com.redhat.thermostat.common.storage.Storage;
-import com.redhat.thermostat.common.storage.Query.Criteria;
 import com.redhat.thermostat.test.MockQuery;
 
 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;
+    private VmCpuStat cpuStat;
 
     @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);
+        cpuStat = new VmCpuStat(TIMESTAMP, VM_ID, CPU_LOAD);
     }
 
     @Test
@@ -96,9 +92,11 @@
     @Test
     public void testGetLatestCpuStatsBasic() {
 
-        Cursor cursor = mock(Cursor.class);
+        @SuppressWarnings("unchecked")
+        Cursor<VmCpuStat> cursor = mock(Cursor.class);
         when(cursor.hasNext()).thenReturn(true).thenReturn(false);
-        when(cursor.next()).thenReturn(chunk);
+        when(cursor.next()).thenReturn(cpuStat);
+        when(cursor.sort(any(Key.class), any(SortDirection.class))).thenReturn(cursor);
 
         Storage storage = mock(Storage.class);
         when(storage.createQuery()).then(new Answer<Query>() {
@@ -107,7 +105,7 @@
                 return new MockQuery();
             }
         });
-        when(storage.findAll(any(Query.class))).thenReturn(cursor);
+        when(storage.findAllPojos(any(Query.class), same(VmCpuStat.class))).thenReturn(cursor);
 
         HostRef hostRef = mock(HostRef.class);
         when(hostRef.getAgentId()).thenReturn("system");
@@ -121,7 +119,7 @@
         List<VmCpuStat> vmCpuStats = dao.getLatestVmCpuStats(vmRef);
 
         ArgumentCaptor<MockQuery> arg = ArgumentCaptor.forClass(MockQuery.class);
-        verify(storage).findAll(arg.capture());
+        verify(storage).findAllPojos(arg.capture(), same(VmCpuStat.class));
         assertFalse(arg.getValue().hasWhereClauseFor(Key.TIMESTAMP));
 
         assertEquals(1, vmCpuStats.size());
@@ -134,9 +132,12 @@
     @Test
     public void testGetLatestCpuStatsTwice() {
 
-        Cursor cursor = mock(Cursor.class);
+        @SuppressWarnings("unchecked")
+        Cursor<VmCpuStat> cursor = mock(Cursor.class);
         when(cursor.hasNext()).thenReturn(true).thenReturn(false);
-        when(cursor.next()).thenReturn(chunk);
+        when(cursor.next()).thenReturn(cpuStat);
+        when(cursor.sort(any(Key.class), any(SortDirection.class))).thenReturn(cursor);
+        when(cursor.limit(anyInt())).thenReturn(cursor);
 
         Storage storage = mock(Storage.class);
         when(storage.createQuery()).then(new Answer<Query>() {
@@ -145,7 +146,7 @@
                 return new MockQuery();
             }
         });
-        when(storage.findAll(any(Query.class))).thenReturn(cursor);
+        when(storage.findAllPojos(any(Query.class), same(VmCpuStat.class))).thenReturn(cursor);
 
         HostRef hostRef = mock(HostRef.class);
         when(hostRef.getAgentId()).thenReturn("system");
@@ -159,7 +160,7 @@
 
         dao.getLatestVmCpuStats(vmRef);
         ArgumentCaptor<MockQuery> arg = ArgumentCaptor.forClass(MockQuery.class);
-        verify(storage, times(2)).findAll(arg.capture());
+        verify(storage, times(2)).findAllPojos(arg.capture(), same(VmCpuStat.class));
         assertTrue(arg.getValue().hasWhereClause(Key.TIMESTAMP, Criteria.GREATER_THAN, 1234l));
     }
 
--- a/common/core/src/test/java/com/redhat/thermostat/common/dao/VmGcStatConverterTest.java	Tue Sep 11 22:59:49 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +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 org.junit.Test;
-
-import com.redhat.thermostat.common.model.VmGcStat;
-import com.redhat.thermostat.common.storage.Chunk;
-import com.redhat.thermostat.common.storage.Key;
-
-public class VmGcStatConverterTest {
-
-    @Test
-    public void testVmGcStatToChunk() {
-        final Integer VM_ID = 123;
-        final Long TIMESTAMP = 456L;
-        final String COLLECTOR = "collector1";
-        final Long RUN_COUNT = 10L;
-        final Long WALL_TIME = 9L;
-
-        VmGcStat stat = new VmGcStat(VM_ID, TIMESTAMP, COLLECTOR, RUN_COUNT, WALL_TIME);
-        Chunk chunk = new VmGcStatConverter().toChunk(stat);
-
-        assertNotNull(chunk);
-        assertEquals("vm-gc-stats", chunk.getCategory().getName());
-        assertEquals(TIMESTAMP, chunk.get(new Key<Long>("timeStamp", false)));
-        assertEquals(VM_ID, chunk.get(new Key<Integer>("vmId", true)));
-        assertEquals(COLLECTOR, chunk.get(new Key<String>("collectorName", false)));
-        assertEquals(RUN_COUNT, chunk.get(new Key<Long>("runCount", false)));
-        assertEquals(WALL_TIME, chunk.get(new Key<Long>("wallTime", false)));
-    }
-
-    @Test
-    public void testChunkToVmGcStat() {
-        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);
-        chunk.put(VmGcStatDAO.collectorKey, COLLECTOR);
-        chunk.put(VmGcStatDAO.runCountKey, RUN_COUNT);
-        chunk.put(VmGcStatDAO.wallTimeKey, WALL_TIME);
-        VmGcStat stat = new VmGcStatConverter().fromChunk(chunk);
-
-        assertNotNull(stat);
-        assertEquals(TIMESTAMP, (Long) stat.getTimeStamp());
-        assertEquals(VM_ID, (Integer) stat.getVmId());
-        assertEquals(COLLECTOR, stat.getCollectorName());
-        assertEquals(RUN_COUNT, (Long) stat.getRunCount());
-        assertEquals(WALL_TIME, (Long) stat.getWallTime());
-    }
-}
--- a/common/core/src/test/java/com/redhat/thermostat/common/dao/VmGcStatDAOTest.java	Tue Sep 11 22:59:49 2012 +0200
+++ b/common/core/src/test/java/com/redhat/thermostat/common/dao/VmGcStatDAOTest.java	Thu Sep 13 17:13:25 2012 +0200
@@ -38,15 +38,14 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.same;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-
 import java.util.Collection;
 import java.util.List;
 
@@ -56,12 +55,12 @@
 import org.mockito.stubbing.Answer;
 
 import com.redhat.thermostat.common.model.VmGcStat;
-import com.redhat.thermostat.common.storage.Chunk;
 import com.redhat.thermostat.common.storage.Cursor;
+import com.redhat.thermostat.common.storage.Cursor.SortDirection;
 import com.redhat.thermostat.common.storage.Key;
 import com.redhat.thermostat.common.storage.Query;
+import com.redhat.thermostat.common.storage.Query.Criteria;
 import com.redhat.thermostat.common.storage.Storage;
-import com.redhat.thermostat.common.storage.Query.Criteria;
 import com.redhat.thermostat.test.MockQuery;
 
 public class VmGcStatDAOTest {
@@ -88,20 +87,17 @@
     @Test
     public void testGetLatestVmGcStatsBasic() {
 
-        Chunk chunk = new Chunk(VmGcStatDAO.vmGcStatCategory, false);
-        chunk.put(Key.TIMESTAMP, TIMESTAMP);
-        chunk.put(Key.VM_ID, VM_ID);
-        chunk.put(VmGcStatDAO.collectorKey, COLLECTOR);
-        chunk.put(VmGcStatDAO.runCountKey, RUN_COUNT);
-        chunk.put(VmGcStatDAO.wallTimeKey, WALL_TIME);
+        VmGcStat vmGcStat = new VmGcStat(VM_ID, TIMESTAMP, COLLECTOR, RUN_COUNT, WALL_TIME);
 
-        Cursor cursor = mock(Cursor.class);
+        @SuppressWarnings("unchecked")
+        Cursor<VmGcStat> cursor = mock(Cursor.class);
         when(cursor.hasNext()).thenReturn(true).thenReturn(false);
-        when(cursor.next()).thenReturn(chunk);
+        when(cursor.next()).thenReturn(vmGcStat);
+        when(cursor.sort(any(Key.class), any(SortDirection.class))).thenReturn(cursor);
 
         Storage storage = mock(Storage.class);
         when(storage.createQuery()).thenReturn(new MockQuery());
-        when(storage.findAll(any(Query.class))).thenReturn(cursor);
+        when(storage.findAllPojos(any(Query.class), same(VmGcStat.class))).thenReturn(cursor);
 
         HostRef hostRef = mock(HostRef.class);
         when(hostRef.getAgentId()).thenReturn("system");
@@ -115,7 +111,7 @@
         List<VmGcStat> vmGcStats = dao.getLatestVmGcStats(vmRef);
 
         ArgumentCaptor<MockQuery> arg = ArgumentCaptor.forClass(MockQuery.class);
-        verify(storage).findAll(arg.capture());
+        verify(storage).findAllPojos(arg.capture(), same(VmGcStat.class));
         assertFalse(arg.getValue().hasWhereClauseFor(Key.TIMESTAMP));
 
         assertEquals(1, vmGcStats.size());
@@ -130,17 +126,13 @@
     @Test
     public void testGetLatestVmGcStatsTwice() {
 
-        Chunk chunk = new Chunk(VmGcStatDAO.vmGcStatCategory, false);
-        chunk.put(Key.TIMESTAMP, TIMESTAMP);
-        chunk.put(Key.VM_ID, VM_ID);
-        chunk.put(VmGcStatDAO.collectorKey, COLLECTOR);
-        chunk.put(VmGcStatDAO.runCountKey, RUN_COUNT);
-        chunk.put(VmGcStatDAO.wallTimeKey, WALL_TIME);
+        VmGcStat vmGcStat = new VmGcStat(VM_ID, TIMESTAMP, COLLECTOR, RUN_COUNT, WALL_TIME);
 
-        Cursor cursor = mock(Cursor.class);
+        @SuppressWarnings("unchecked")
+        Cursor<VmGcStat> cursor = mock(Cursor.class);
         when(cursor.hasNext()).thenReturn(true).thenReturn(false);
-        when(cursor.next()).thenReturn(chunk);
-
+        when(cursor.next()).thenReturn(vmGcStat);
+        when(cursor.sort(any(Key.class), any(SortDirection.class))).thenReturn(cursor);
         Storage storage = mock(Storage.class);
 
         when(storage.createQuery()).then(new Answer<MockQuery>() {
@@ -149,7 +141,7 @@
                 return new MockQuery();
             }
         });
-        when(storage.findAll(any(Query.class))).thenReturn(cursor);
+        when(storage.findAllPojos(any(Query.class), same(VmGcStat.class))).thenReturn(cursor);
 
         HostRef hostRef = mock(HostRef.class);
         when(hostRef.getAgentId()).thenReturn("system");
@@ -163,7 +155,7 @@
 
         dao.getLatestVmGcStats(vmRef);
         ArgumentCaptor<MockQuery> arg = ArgumentCaptor.forClass(MockQuery.class);
-        verify(storage, times(2)).findAll(arg.capture());
+        verify(storage, times(2)).findAllPojos(arg.capture(), same(VmGcStat.class));
         MockQuery query = arg.getValue();
         assertTrue(query.hasWhereClause(Key.TIMESTAMP, Criteria.GREATER_THAN, 456l));
     }
--- a/common/core/src/test/java/com/redhat/thermostat/common/dao/VmInfoDAOTest.java	Tue Sep 11 22:59:49 2012 +0200
+++ b/common/core/src/test/java/com/redhat/thermostat/common/dao/VmInfoDAOTest.java	Thu Sep 13 17:13:25 2012 +0200
@@ -197,17 +197,18 @@
           .from(VmInfoDAO.vmInfoCategory)
           .where(Key.AGENT_ID, Criteria.EQUALS, "123");
 
-      Chunk vm1 = new Chunk(VmInfoDAO.vmInfoCategory, false);
-      vm1.put(Key.VM_ID, 123);
-      vm1.put(VmInfoDAO.mainClassKey, "mainClass1");
+      VmInfo vm1 = new VmInfo();
+      vm1.setVmPid(123);
+      vm1.setMainClass("mainClass1");
 
-      Cursor singleVMCursor = mock(Cursor.class);
+      @SuppressWarnings("unchecked")
+      Cursor<VmInfo> singleVMCursor = mock(Cursor.class);
       when(singleVMCursor.hasNext()).thenReturn(true).thenReturn(false);
       when(singleVMCursor.next()).thenReturn(vm1);
 
       Storage storage = mock(Storage.class);
       when(storage.createQuery()).thenReturn(new MockQuery());
-      when(storage.findAll(expectedQuery)).thenReturn(singleVMCursor);
+      when(storage.findAllPojos(expectedQuery, VmInfo.class)).thenReturn(singleVMCursor);
       return storage;
   }
 
@@ -228,21 +229,22 @@
           .from(VmInfoDAO.vmInfoCategory)
           .where(Key.AGENT_ID, Criteria.EQUALS, "456");
 
-      Chunk vm1 = new Chunk(VmInfoDAO.vmInfoCategory, false);
-      vm1.put(Key.VM_ID, 123);
-      vm1.put(VmInfoDAO.mainClassKey, "mainClass1");
+      VmInfo vm1 = new VmInfo();
+      vm1.setVmPid(123);
+      vm1.setMainClass("mainClass1");
 
-      Chunk vm2 = new Chunk(VmInfoDAO.vmInfoCategory, false);
-      vm2.put(Key.VM_ID, 456);
-      vm2.put(VmInfoDAO.mainClassKey, "mainClass2");
+      VmInfo vm2 = new VmInfo();
+      vm2.setVmPid(456);
+      vm2.setMainClass("mainClass2");
 
-      Cursor multiVMsCursor = mock(Cursor.class);
+      @SuppressWarnings("unchecked")
+      Cursor<VmInfo> 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.createQuery()).thenReturn(new MockQuery());
-      when(storage.findAll(expectedQuery)).thenReturn(multiVMsCursor);
+      when(storage.findAllPojos(expectedQuery, VmInfo.class)).thenReturn(multiVMsCursor);
       return storage;
   }
 
--- a/common/core/src/test/java/com/redhat/thermostat/common/dao/VmLatestPojoListGetterTest.java	Tue Sep 11 22:59:49 2012 +0200
+++ b/common/core/src/test/java/com/redhat/thermostat/common/dao/VmLatestPojoListGetterTest.java	Thu Sep 13 17:13:25 2012 +0200
@@ -40,7 +40,7 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.isA;
+import static org.mockito.Matchers.same;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -53,8 +53,8 @@
 
 import com.redhat.thermostat.common.model.VmClassStat;
 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.Cursor.SortDirection;
 import com.redhat.thermostat.common.storage.Key;
 import com.redhat.thermostat.common.storage.Query;
 import com.redhat.thermostat.common.storage.Query.Criteria;
@@ -81,29 +81,15 @@
 
     private HostRef hostRef;
     private VmRef vmRef;
-    private Converter<VmClassStat> converter;
-    private Chunk result1, result2, result3;
+    private VmClassStat result1, result2, result3;
 
     @Before
     public void setUp() {
         hostRef = new HostRef(AGENT_ID, HOSTNAME);
         vmRef = new VmRef(hostRef, VM_PID, MAIN_CLASS);
-        converter = new VmClassStatConverter();
-        result1 = new Chunk(cat, false);
-        result1.put(Key.AGENT_ID, AGENT_ID);
-        result1.put(Key.VM_ID, VM_PID);
-        result1.put(Key.TIMESTAMP, t1);
-        result1.put(VmClassStatDAO.loadedClassesKey, lc1);
-        result2 = new Chunk(cat, false);
-        result2.put(Key.AGENT_ID, AGENT_ID);
-        result2.put(Key.VM_ID, VM_PID);
-        result2.put(Key.TIMESTAMP, t2);
-        result2.put(VmClassStatDAO.loadedClassesKey, lc2);
-        result3 = new Chunk(cat, false);
-        result3.put(Key.AGENT_ID, AGENT_ID);
-        result3.put(Key.VM_ID, VM_PID);
-        result3.put(Key.TIMESTAMP, t3);
-        result3.put(VmClassStatDAO.loadedClassesKey, lc3);
+        result1 = new VmClassStat(VM_PID, t1, lc1);
+        result2 = new VmClassStat(VM_PID, t2, lc2);
+        result3 = new VmClassStat(VM_PID, t3, lc3);
     }
 
     @Test
@@ -112,7 +98,7 @@
         MockQuery query = new MockQuery();
         when(storage.createQuery()).thenReturn(query);
 
-        VmLatestPojoListGetter<VmClassStat> getter = new VmLatestPojoListGetter<>(storage, cat, converter, vmRef);
+        VmLatestPojoListGetter<VmClassStat> getter = new VmLatestPojoListGetter<>(storage, cat, vmRef, VmClassStat.class);
         query = (MockQuery) getter.buildQuery();
 
         assertNotNull(query);
@@ -128,7 +114,7 @@
         MockQuery query = new MockQuery();
         when(storage.createQuery()).thenReturn(query);
 
-        VmLatestPojoListGetter<VmClassStat> getter = new VmLatestPojoListGetter<>(storage, cat, converter, vmRef, 123);
+        VmLatestPojoListGetter<VmClassStat> getter = new VmLatestPojoListGetter<>(storage, cat, vmRef, VmClassStat.class, 123);
         query = (MockQuery) getter.buildQuery();
 
         assertNotNull(query);
@@ -146,7 +132,7 @@
         MockQuery query = new MockQuery();
         when(storage.createQuery()).thenReturn(ignored).thenReturn(query);
 
-        VmLatestPojoListGetter<VmClassStat> getter = new VmLatestPojoListGetter<>(storage, cat, converter, vmRef);
+        VmLatestPojoListGetter<VmClassStat> getter = new VmLatestPojoListGetter<>(storage, cat, vmRef, VmClassStat.class);
         getter.buildQuery(); // Ignore first return value.
         query = (MockQuery) getter.buildQuery();
 
@@ -160,15 +146,17 @@
 
     @Test
     public void testGetLatest() {
-        Cursor cursor = mock(Cursor.class);
+        @SuppressWarnings("unchecked")
+        Cursor<VmClassStat> cursor = mock(Cursor.class);
         when(cursor.hasNext()).thenReturn(true).thenReturn(true).thenReturn(false);
         when(cursor.next()).thenReturn(result1).thenReturn(result2).thenReturn(null);
+        when(cursor.sort(any(Key.class), any(SortDirection.class))).thenReturn(cursor);
 
         Storage storage = mock(Storage.class);
         when(storage.createQuery()).thenReturn(new MockQuery());
-        when(storage.findAll(any(Query.class))).thenReturn(cursor);
+        when(storage.findAllPojos(any(Query.class), same(VmClassStat.class))).thenReturn(cursor);
 
-        VmLatestPojoListGetter<VmClassStat> getter = new VmLatestPojoListGetter<>(storage, cat, converter, vmRef);
+        VmLatestPojoListGetter<VmClassStat> getter = new VmLatestPojoListGetter<>(storage, cat, vmRef, VmClassStat.class);
 
         List<VmClassStat> stats = getter.getLatest();
 
@@ -184,11 +172,14 @@
 
     @Test
     public void testGetLatestMultipleCalls() {
-        Cursor cursor1 = mock(Cursor.class);
+        @SuppressWarnings("unchecked")
+        Cursor<VmClassStat> cursor1 = mock(Cursor.class);
         when(cursor1.hasNext()).thenReturn(true).thenReturn(true).thenReturn(false);
         when(cursor1.next()).thenReturn(result1).thenReturn(result2).thenReturn(null);
+        when(cursor1.sort(any(Key.class), any(SortDirection.class))).thenReturn(cursor1);
 
-        Cursor cursor2 = mock(Cursor.class);
+        @SuppressWarnings("unchecked")
+        Cursor<VmClassStat> cursor2 = mock(Cursor.class);
         when(cursor2.hasNext()).thenReturn(true).thenReturn(false);
         when(cursor2.next()).thenReturn(result3);
 
@@ -197,13 +188,13 @@
         MockQuery secondQuery = new MockQuery();
         when(storage.createQuery()).thenReturn(firstQuery).thenReturn(secondQuery);
 
-        when(storage.findAll(any(Query.class))).thenReturn(cursor1);
+        when(storage.findAllPojos(any(Query.class), same(VmClassStat.class))).thenReturn(cursor1);
 
-        VmLatestPojoListGetter<VmClassStat> getter = new VmLatestPojoListGetter<>(storage, cat, converter, vmRef);
+        VmLatestPojoListGetter<VmClassStat> getter = new VmLatestPojoListGetter<>(storage, cat, vmRef, VmClassStat.class);
         getter.getLatest();
         getter.getLatest();
 
-        verify(storage, times(2)).findAll(isA(Query.class));
+        verify(storage, times(2)).findAllPojos(any(Query.class), same(VmClassStat.class));
 
         assertTrue(secondQuery.hasWhereClause(Key.AGENT_ID, Criteria.EQUALS, AGENT_ID));
         assertTrue(secondQuery.hasWhereClause(Key.VM_ID, Criteria.EQUALS, VM_PID));
--- a/common/core/src/test/java/com/redhat/thermostat/common/dao/VmMemoryStatDAOTest.java	Tue Sep 11 22:59:49 2012 +0200
+++ b/common/core/src/test/java/com/redhat/thermostat/common/dao/VmMemoryStatDAOTest.java	Thu Sep 13 17:13:25 2012 +0200
@@ -39,6 +39,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.same;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -55,12 +56,11 @@
 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;
-import com.redhat.thermostat.common.storage.Query.Criteria;
 import com.redhat.thermostat.common.storage.Key;
 import com.redhat.thermostat.common.storage.Query;
+import com.redhat.thermostat.common.storage.Query.Criteria;
 import com.redhat.thermostat.common.storage.Storage;
 import com.redhat.thermostat.test.MockQuery;
 
@@ -73,8 +73,9 @@
     private VmRef vmRef;
 
     private MockQuery query;
-    private Cursor cursor;
+    private Cursor<VmMemoryStat> cursor;
 
+    @SuppressWarnings("unchecked")
     @Before
     public void setUp() {
         
@@ -91,7 +92,7 @@
         when(storage.createQuery()).thenReturn(query);
 
         cursor = mock(Cursor.class);
-        when(storage.findAll(any(Query.class))).thenReturn(cursor);
+        when(storage.findAllPojos(any(Query.class), same(VmMemoryStat.class))).thenReturn(cursor);
 
         when(cursor.sort(any(Key.class), any(SortDirection.class))).thenReturn(cursor);
         when(cursor.limit(any(Integer.class))).thenReturn(cursor);
@@ -182,7 +183,7 @@
 
         Storage storage = mock(Storage.class);
         when(storage.createQuery()).thenReturn(new MockQuery());
-        when(storage.findAll(any(Query.class))).thenReturn(cursor);
+        when(storage.findAllPojos(any(Query.class), same(VmMemoryStat.class))).thenReturn(cursor);
 
         VmMemoryStatDAO impl = new VmMemoryStatDAOImpl(storage);
         VmMemoryStat latest = impl.getLatestMemoryStat(vmRef);
--- a/common/core/src/test/java/com/redhat/thermostat/common/storage/MongoCursorTest.java	Tue Sep 11 22:59:49 2012 +0200
+++ b/common/core/src/test/java/com/redhat/thermostat/common/storage/MongoCursorTest.java	Thu Sep 13 17:13:25 2012 +0200
@@ -36,13 +36,12 @@
 
 package com.redhat.thermostat.common.storage;
 
-import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyInt;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -55,9 +54,50 @@
 import com.mongodb.BasicDBObject;
 import com.mongodb.DBCursor;
 import com.mongodb.DBObject;
+import com.redhat.thermostat.common.model.Pojo;
 
 public class MongoCursorTest {
 
+    @Entity
+    public static class TestClass implements Pojo {
+        private String key1;
+        private String key2;
+        private String key3;
+        private String key4;
+        @Persist
+        public String getKey1() {
+            return key1;
+        }
+        @Persist
+        public void setKey1(String key1) {
+            this.key1 = key1;
+        }
+        @Persist
+        public String getKey2() {
+            return key2;
+        }
+        @Persist
+        public void setKey2(String key2) {
+            this.key2 = key2;
+        }
+        @Persist
+        public String getKey3() {
+            return key3;
+        }
+        @Persist
+        public void setKey3(String key3) {
+            this.key3 = key3;
+        }
+        @Persist
+        public String getKey4() {
+            return key4;
+        }
+        @Persist
+        public void setKey4(String key4) {
+            this.key4 = key4;
+        }
+    }
+
     private static final Key<String> key1 = new Key<>("key1", false);
     private static final Key<String> key2 = new Key<>("key2", false);
     private static final Key<String> key3 = new Key<>("key3", false);
@@ -66,7 +106,7 @@
     private static final Category testCategory = new Category("MongoCursorTest", key1, key2, key3, key4);
 
     private DBCursor dbCursor;
-    private Cursor cursor;
+    private Cursor<TestClass> cursor;
 
     @Before
     public void setUp() {
@@ -83,7 +123,7 @@
         when(dbCursor.next()).thenReturn(value1).thenReturn(value2).thenReturn(null);
         when(dbCursor.sort(any(DBObject.class))).thenReturn(dbCursor);
         when(dbCursor.limit(anyInt())).thenReturn(dbCursor);
-        cursor = new MongoCursor(dbCursor, testCategory);
+        cursor = new MongoCursor<TestClass>(dbCursor, testCategory, TestClass.class, null);
 
     }
 
@@ -97,16 +137,14 @@
     public void verifySimpleCursor() {
 
         assertTrue(cursor.hasNext());
-        Chunk chunk1 = cursor.next();
-        assertArrayEquals(new Key<?>[]{key1, key2}, chunk1.getKeys().toArray());
-        assertEquals("test1", chunk1.get(key1));
-        assertEquals("test2", chunk1.get(key2));
+        TestClass obj1 = cursor.next();
+        assertEquals("test1", obj1.getKey1());
+        assertEquals("test2", obj1.getKey2());
 
         assertTrue(cursor.hasNext());
-        Chunk chunk2 = cursor.next();
-        assertArrayEquals(new Key<?>[]{key3, key4}, chunk2.getKeys().toArray());
-        assertEquals("test3", chunk2.get(key3));
-        assertEquals("test4", chunk2.get(key4));
+        TestClass obj2 = cursor.next();
+        assertEquals("test3", obj2.getKey3());
+        assertEquals("test4", obj2.getKey4());
 
         assertFalse(cursor.hasNext());
         assertNull(cursor.next());
@@ -115,7 +153,7 @@
     @Test
     public void verifyCursorSort() {
         ArgumentCaptor<DBObject> arg = ArgumentCaptor.forClass(DBObject.class);
-        Cursor sorted = cursor.sort(key1, Cursor.SortDirection.ASCENDING);
+        Cursor<TestClass> sorted = cursor.sort(key1, Cursor.SortDirection.ASCENDING);
 
         verify(dbCursor).sort(arg.capture());
         DBObject orderByDBObject = arg.getValue();
@@ -133,7 +171,7 @@
     @Test
     public void verifyCursorLimit() {
 
-        Cursor sorted = cursor.limit(1);
+        Cursor<TestClass> sorted = cursor.limit(1);
 
         verify(dbCursor).limit(1);
 
--- a/common/core/src/test/java/com/redhat/thermostat/common/storage/MongoStorageTest.java	Tue Sep 11 22:59:49 2012 +0200
+++ b/common/core/src/test/java/com/redhat/thermostat/common/storage/MongoStorageTest.java	Thu Sep 13 17:13:25 2012 +0200
@@ -75,12 +75,62 @@
 import com.mongodb.gridfs.GridFSDBFile;
 import com.mongodb.gridfs.GridFSInputFile;
 import com.redhat.thermostat.common.config.StartupConfiguration;
+import com.redhat.thermostat.common.model.Pojo;
 import com.redhat.thermostat.common.storage.Query.Criteria;
 
 @RunWith(PowerMockRunner.class)
 @PrepareForTest({ DBCollection.class, DB.class, Mongo.class, MongoStorage.class, MongoConnection.class })
 public class MongoStorageTest {
 
+    @Entity
+    public static class TestClass implements Pojo {
+        private String key1;
+        private String key2;
+        private String key3;
+        private String key4;
+        private String key5;
+        @Persist
+        public String getKey1() {
+            return key1;
+        }
+        @Persist
+        public void setKey1(String key1) {
+            this.key1 = key1;
+        }
+        @Persist
+        public String getKey2() {
+            return key2;
+        }
+        @Persist
+        public void setKey2(String key2) {
+            this.key2 = key2;
+        }
+        @Persist
+        public String getKey3() {
+            return key3;
+        }
+        @Persist
+        public void setKey3(String key3) {
+            this.key3 = key3;
+        }
+        @Persist
+        public String getKey4() {
+            return key4;
+        }
+        @Persist
+        public void setKey4(String key4) {
+            this.key4 = key4;
+        }
+        @Persist
+        public String getKey5() {
+            return key5;
+        }
+        @Persist
+        public void setKey5(String key5) {
+            this.key5 = key5;
+        }
+    }
+
     private static final Key<String> key1 = new Key<>("key1", false);
     private static final Key<String> key2 = new Key<>("key2", false);
     private static final Key<String> key3 = new Key<>("key3", false);
@@ -170,10 +220,10 @@
     }
 
     @Test (expected=IllegalArgumentException.class)
-    public void veirfyFindAllOnlyAcceptsMongoQuery() {
+    public void verifyFindAllOnlyAcceptsMongoQuery() {
         MongoStorage storage = makeStorage();
         Query query = mock(Query.class);
-        storage.findAll(query);
+        storage.findAllPojos(query, TestClass.class);
     }
 
     @Test
@@ -181,7 +231,7 @@
         PowerMockito.whenNew(Mongo.class).withParameterTypes(MongoURI.class).withArguments(any(MongoURI.class)).thenReturn(m);
         MongoStorage storage = makeStorage();
         Query query = storage.createQuery().from(testCategory);
-        Cursor cursor = storage.findAll(query);
+        Cursor<TestClass> cursor = storage.findAllPojos(query, TestClass.class);
         assertNotNull(cursor);
     }
 
@@ -199,7 +249,7 @@
         PowerMockito.whenNew(Mongo.class).withParameterTypes(MongoURI.class).withArguments(any(MongoURI.class)).thenReturn(m);
         MongoStorage storage = makeStorage();
         Query query = storage.createQuery().from(testCategory);
-        storage.findAll(query);
+        storage.findAllPojos(query, TestClass.class);
         verify(testCollection).find(any(DBObject.class));
     }
 
@@ -224,7 +274,7 @@
         when(query.getCategory()).thenReturn(testCategory);
         ArgumentCaptor<DBObject> findArg = ArgumentCaptor.forClass(DBObject.class);
 
-        storage.findAll(query);
+        storage.findAllPojos(query, TestClass.class);
 
         verify(testCollection).find(findArg.capture());
         assertSame(generatedQuery, findArg.getValue());
@@ -273,7 +323,7 @@
         // Because we mock the DBCollection, the contents of this query don't actually determine the result.
         MongoQuery query = new MongoQuery().from(testCategory);
 
-        Cursor cursor = storage.findAll(query);
+        Cursor<TestClass> cursor = storage.findAllPojos(query, TestClass.class);
 
         verifyDefaultCursor(cursor);
     }
@@ -282,7 +332,7 @@
     public void verifyFindAllFromCategoryCallsDBCollectionFindAll() throws Exception {
         PowerMockito.whenNew(Mongo.class).withParameterTypes(MongoURI.class).withArguments(any(MongoURI.class)).thenReturn(m);
         MongoStorage storage = makeStorage();
-        storage.findAllFromCategory(testCategory);
+        storage.findAllPojosFromCategory(testCategory, TestClass.class);
         verify(testCollection).find();
     }
 
@@ -290,7 +340,7 @@
     public void verifyFindAllFromCategoryReturnsCorrectCursor() throws Exception {
         PowerMockito.whenNew(Mongo.class).withParameterTypes(MongoURI.class).withArguments(any(MongoURI.class)).thenReturn(m);
         MongoStorage storage = makeStorage();
-        Cursor cursor = storage.findAllFromCategory(testCategory);
+        Cursor<TestClass> cursor = storage.findAllPojosFromCategory(testCategory, TestClass.class);
 
         verifyDefaultCursor(cursor);
     }
@@ -320,18 +370,16 @@
         assertEquals(0, count);
     }
 
-    private void verifyDefaultCursor(Cursor cursor) {
+    private void verifyDefaultCursor(Cursor<TestClass> cursor) {
         assertTrue(cursor.hasNext());
-        Chunk chunk1 = cursor.next();
-        assertArrayEquals(new Key<?>[]{key1, key2}, chunk1.getKeys().toArray());
-        assertEquals("test1", chunk1.get(key1));
-        assertEquals("test2", chunk1.get(key2));
+        TestClass obj1 = cursor.next();
+        assertEquals("test1", obj1.getKey1());
+        assertEquals("test2", obj1.getKey2());
 
         assertTrue(cursor.hasNext());
-        Chunk chunk2 = cursor.next();
-        assertArrayEquals(new Key<?>[]{key3, key4}, chunk2.getKeys().toArray());
-        assertEquals("test3", chunk2.get(key3));
-        assertEquals("test4", chunk2.get(key4));
+        TestClass obj2 = cursor.next();
+        assertEquals("test3", obj2.getKey3());
+        assertEquals("test4", obj2.getKey4());
 
         assertFalse(cursor.hasNext());
         assertNull(cursor.next());
--- a/thread/collector/src/main/java/com/redhat/thermostat/thread/dao/impl/ThreadDaoImpl.java	Tue Sep 11 22:59:49 2012 +0200
+++ b/thread/collector/src/main/java/com/redhat/thermostat/thread/dao/impl/ThreadDaoImpl.java	Thu Sep 13 17:13:25 2012 +0200
@@ -41,7 +41,6 @@
 
 import com.redhat.thermostat.common.dao.VmRef;
 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.Query;
@@ -94,13 +93,9 @@
         ThreadSummary summary = null;
 
         Query query = prepareQuery(THREAD_SUMMARY, ref);
-        Cursor cursor = storage.findAll(query).sort(Key.TIMESTAMP, Cursor.SortDirection.DESCENDING).limit(1);
+        Cursor<ThreadSummary> cursor = storage.findAllPojos(query, ThreadSummary.class).sort(Key.TIMESTAMP, Cursor.SortDirection.DESCENDING).limit(1);
         if (cursor.hasNext()) {
-            Chunk found = cursor.next();
-            summary = new ThreadSummary();
-            summary.setTimeStamp(found.get(Key.TIMESTAMP));
-            summary.setCurrentLiveThreads(found.get(LIVE_THREADS_KEY));
-            summary.setCurrentDaemonThreads(found.get(DAEMON_THREADS_KEY));
+            summary = cursor.next();
         }
         
         return summary;
@@ -114,14 +109,9 @@
         Query query = prepareQuery(THREAD_SUMMARY, ref);
         query.where(Key.TIMESTAMP, Criteria.GREATER_THAN, since);
 
-        Cursor cursor = storage.findAll(query).sort(Key.TIMESTAMP, Cursor.SortDirection.DESCENDING);
+        Cursor<ThreadSummary> cursor = storage.findAllPojos(query, ThreadSummary.class).sort(Key.TIMESTAMP, Cursor.SortDirection.DESCENDING);
         while (cursor.hasNext()) {
-            ThreadSummary summary = new ThreadSummary();
-            
-            Chunk found = cursor.next();
-            summary.setTimeStamp(found.get(Key.TIMESTAMP));
-            summary.setCurrentLiveThreads(found.get(LIVE_THREADS_KEY));
-            summary.setCurrentDaemonThreads(found.get(DAEMON_THREADS_KEY));
+            ThreadSummary summary = cursor.next();
             result.add(summary);
         }
         
@@ -140,22 +130,9 @@
         Query query = prepareQuery(THREAD_INFO, ref)
                 .where(Key.TIMESTAMP, Criteria.GREATER_THAN, since);
         
-        Cursor cursor = storage.findAll(query).sort(Key.TIMESTAMP, Cursor.SortDirection.DESCENDING);
+        Cursor<ThreadInfoData> cursor = storage.findAllPojos(query, ThreadInfoData.class).sort(Key.TIMESTAMP, Cursor.SortDirection.DESCENDING);
         while (cursor.hasNext()) {
-            ThreadInfoData info = new ThreadInfoData();
-            
-            Chunk found = cursor.next();
-            info.setTimeStamp(found.get(Key.TIMESTAMP));
-            
-            info.setThreadId(found.get(THREAD_ID_KEY));
-            info.setThreadName(found.get(THREAD_NAME_KEY));
-            info.setThreadState(Thread.State.valueOf(found.get(THREAD_STATE_KEY)));
-
-            info.setThreadBlockedCount(found.get(THREAD_BLOCKED_COUNT_KEY));
-            info.setThreadWaitCount(found.get(THREAD_WAIT_COUNT_KEY));
-            info.setThreadCpuTime(found.get(THREAD_CPU_TIME_KEY));
-            info.setThreadUserTime(found.get(THREAD_USER_TIME_KEY));
-
+            ThreadInfoData info = cursor.next();
             result.add(info);
         }