Mercurial > hg > release > thermostat-0.7
changeset 749:769d409c83b6
Overhaul and improvement of pojo conversion.
Reviewed-by: neugens
Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2012-October/003939.html
line wrap: on
line diff
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/HostCpuController.java Fri Oct 26 13:12:46 2012 +0200 +++ b/client/core/src/main/java/com/redhat/thermostat/client/ui/HostCpuController.java Fri Oct 26 13:13:42 2012 +0200 @@ -134,12 +134,12 @@ List<CpuStat> cpuStats = cpuStatDAO.getLatestCpuStats(ref, lastSeenTimeStamp); List<List<DiscreteTimeData<Double>>> results = new ArrayList<>(); for (CpuStat stat : cpuStats) { - List<Double> data = stat.getPerProcessorUsage(); - for (int i = 0 ; i < data.size(); i++) { + double[] data = stat.getPerProcessorUsage(); + for (int i = 0 ; i < data.length; i++) { if (results.size() == i) { results.add(new ArrayList<DiscreteTimeData<Double>>()); } - results.get(i).add(new DiscreteTimeData<Double>(stat.getTimeStamp(), data.get(i))); + results.get(i).add(new DiscreteTimeData<Double>(stat.getTimeStamp(), data[i])); lastSeenTimeStamp = Math.max(lastSeenTimeStamp, stat.getTimeStamp()); } }
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/VmGcController.java Fri Oct 26 13:12:46 2012 +0200 +++ b/client/core/src/main/java/com/redhat/thermostat/client/ui/VmGcController.java Fri Oct 26 13:13:42 2012 +0200 @@ -183,8 +183,8 @@ VmMemoryStat info = memDao.getLatestMemoryStat(ref); for (Generation g: info.getGenerations()) { - if (g.collector.equals(collectorName)) { - return g.name; + if (g.getCollector().equals(collectorName)) { + return g.getName(); } } return translator.localize(LocaleResources.UNKNOWN_GEN);
--- a/client/core/src/test/java/com/redhat/thermostat/client/ui/HostCpuControllerTest.java Fri Oct 26 13:12:46 2012 +0200 +++ b/client/core/src/test/java/com/redhat/thermostat/client/ui/HostCpuControllerTest.java Fri Oct 26 13:13:42 2012 +0200 @@ -71,7 +71,6 @@ import com.redhat.thermostat.common.model.CpuStat; import com.redhat.thermostat.common.model.DiscreteTimeData; import com.redhat.thermostat.common.model.HostInfo; -import com.redhat.thermostat.common.utils.ArrayUtils; public class HostCpuControllerTest { @@ -103,8 +102,8 @@ HostInfoDAO hostInfoDAO = mock(HostInfoDAO.class); when(hostInfoDAO.getHostInfo(any(HostRef.class))).thenReturn(hostInfo); - CpuStat cpuStat1 = new CpuStat(1l, ArrayUtils.toDoubleList(new double[] {10.0, 20.0, 30.0})); - CpuStat cpuStat2 = new CpuStat(2l, ArrayUtils.toDoubleList(new double[] {15.0, 25.0, 35.0})); + CpuStat cpuStat1 = new CpuStat(1l, new double[] {10.0, 20.0, 30.0}); + CpuStat cpuStat2 = new CpuStat(2l, new double[] {15.0, 25.0, 35.0}); CpuStatDAO cpuStatDAO = mock(CpuStatDAO.class); when(cpuStatDAO.getLatestCpuStats(any(HostRef.class), anyLong())).thenReturn(Arrays.asList(cpuStat1, cpuStat2));
--- a/client/core/src/test/java/com/redhat/thermostat/client/ui/VmGcControllerTest.java Fri Oct 26 13:12:46 2012 +0200 +++ b/client/core/src/test/java/com/redhat/thermostat/client/ui/VmGcControllerTest.java Fri Oct 26 13:13:42 2012 +0200 @@ -98,12 +98,10 @@ stats.add(stat2); Generation gen; - List<Generation> gens = new ArrayList<>(); gen = new Generation(); - gen.name = "generation 1"; - gen.collector = "collector1"; - gens.add(gen); - VmMemoryStat memoryStat = new VmMemoryStat(1, 42, gens); + gen.setName("generation 1"); + gen.setCollector("collector1"); + VmMemoryStat memoryStat = new VmMemoryStat(1, 42, new Generation[] { gen }); // Setup DAO VmGcStatDAO vmGcStatDAO = mock(VmGcStatDAO.class);
--- a/client/heapdumper/src/main/java/com/redhat/thermostat/client/heap/HeapDumpController.java Fri Oct 26 13:12:46 2012 +0200 +++ b/client/heapdumper/src/main/java/com/redhat/thermostat/client/heap/HeapDumpController.java Fri Oct 26 13:13:42 2012 +0200 @@ -232,21 +232,21 @@ long used = 0l; long capacity = 0l; long max = 0l; - List<Generation> generations = memoryStats.getGenerations(); + Generation[] generations = memoryStats.getGenerations(); for (Generation generation : generations) { // non heap - if (generation.name.equals("perm")) { + if (generation.getName().equals("perm")) { continue; } - List<Space> spaces = generation.spaces; + Space[] spaces = generation.getSpaces(); for (Space space: spaces) { - used += space.used; - capacity += space.capacity; + used += space.getUsed(); + capacity += space.getCapacity(); // TODO - max =+ space.maxCapacity; + max =+ space.getMaxCapacity(); } } model.addData(memoryStats.getTimeStamp(), used, capacity);
--- a/client/heapdumper/src/test/java/com/redhat/thermostat/client/heap/HeapDumpControllerTest.java Fri Oct 26 13:12:46 2012 +0200 +++ b/client/heapdumper/src/test/java/com/redhat/thermostat/client/heap/HeapDumpControllerTest.java Fri Oct 26 13:13:42 2012 +0200 @@ -326,14 +326,14 @@ final long CAPACITY = 10; final long USED = 5; Space space = new Space(); - space.capacity = CAPACITY; - space.maxCapacity = 20; - space.used = USED; + space.setCapacity(CAPACITY); + space.setMaxCapacity(20); + space.setUsed(USED); Generation gen = new Generation(); - gen.name = "foobar"; - gen.spaces = Arrays.asList(space); + gen.setName("foobar"); + gen.setSpaces(new Space[] { space }); VmMemoryStat stat = new VmMemoryStat(); - stat.setGenerations(Arrays.asList(gen)); + stat.setGenerations(new Generation[] { gen }); when(vmDao.getLatestVmMemoryStats(isA(VmRef.class), anyLong())).thenReturn(Arrays.asList(stat)); @@ -351,15 +351,15 @@ final long DATA_TIMESTAMP = System.currentTimeMillis() + 1000000000; Space space = new Space(); - space.capacity = 10; - space.maxCapacity = 20; - space.used = 5; + space.setCapacity(10); + space.setMaxCapacity(20); + space.setUsed(5); Generation gen = new Generation(); - gen.name = "foobar"; - gen.spaces = Arrays.asList(space); + gen.setName("foobar"); + gen.setSpaces(new Space[] { space }); VmMemoryStat stat = new VmMemoryStat(); stat.setTimeStamp(DATA_TIMESTAMP); - stat.setGenerations(Arrays.asList(gen)); + stat.setGenerations(new Generation[] { gen }); when(vmDao.getLatestVmMemoryStats(isA(VmRef.class), anyLong())).thenReturn(Arrays.asList(stat));
--- a/client/memory-stats-panel/src/main/java/com/redhat/thermostat/client/stats/memory/MemoryStatsController.java Fri Oct 26 13:12:46 2012 +0200 +++ b/client/memory-stats-panel/src/main/java/com/redhat/thermostat/client/stats/memory/MemoryStatsController.java Fri Oct 26 13:13:42 2012 +0200 @@ -79,34 +79,34 @@ public void run() { List<VmMemoryStat> vmInfo = vmDao.getLatestVmMemoryStats(ref, desiredUpdateTimeStamp); for (VmMemoryStat memoryStats: vmInfo) { - List<Generation> generations = memoryStats.getGenerations(); + Generation[] generations = memoryStats.getGenerations(); for (Generation generation : generations) { - List<Space> spaces = generation.spaces; + Space[] spaces = generation.getSpaces(); for (Space space: spaces) { - Payload payload = regions.get(space.name); + Payload payload = regions.get(space.getName()); if (payload == null) { payload = new Payload(); - payload.setName(space.name); + payload.setName(space.getName()); } - Scale usedScale = normalizeScale(space.used, space.capacity); - double used = Scale.convertTo(usedScale, space.used, 100); - double maxUsed = Scale.convertTo(usedScale, space.capacity, 100); + Scale usedScale = normalizeScale(space.getUsed(), space.getCapacity()); + double used = Scale.convertTo(usedScale, space.getUsed(), 100); + double maxUsed = Scale.convertTo(usedScale, space.getCapacity(), 100); payload.setUsed(used); payload.setMaxUsed(maxUsed); payload.setUsedUnit(usedScale); - Scale maxScale = normalizeScale(space.capacity, space.maxCapacity); - double capacity = Scale.convertTo(maxScale, space.capacity, 100); - double maxCapacity = Scale.convertTo(maxScale, space.maxCapacity, 100); + Scale maxScale = normalizeScale(space.getCapacity(), space.getMaxCapacity()); + double capacity = Scale.convertTo(maxScale, space.getCapacity(), 100); + double maxCapacity = Scale.convertTo(maxScale, space.getMaxCapacity(), 100); payload.setCapacity(capacity); payload.setMaxCapacity(maxCapacity); payload.setCapacityUnit(maxScale); - String tooltip = space.name + ": used: " + used + " " + usedScale + + String tooltip = space.getName() + ": used: " + used + " " + usedScale + ", capacity: " + capacity + " " + maxScale + ", max capacity: " + maxCapacity + " " + maxScale; @@ -115,20 +115,20 @@ StatsModel model = payload.getModel(); if (model == null) { model = new StatsModel(); - model.setName(space.name); + model.setName(space.getName()); model.setRange(3600); } // normalize this always in the same unit model.addData(memoryStats.getTimeStamp(), - Scale.convertTo(Scale.MiB, space.used, 100)); + Scale.convertTo(Scale.MiB, space.getUsed(), 100)); payload.setModel(model); - if (regions.containsKey(space.name)) { + if (regions.containsKey(space.getName())) { view.updateRegion(payload.clone()); } else { view.addRegion(payload.clone()); - regions.put(space.name, payload); + regions.put(space.getName(), payload); } view.requestRepaint();
--- a/client/memory-stats-panel/src/test/java/com/redhat/thermostat/client/stats/memory/MemoryStatsControllerTest.java Fri Oct 26 13:12:46 2012 +0200 +++ b/client/memory-stats-panel/src/test/java/com/redhat/thermostat/client/stats/memory/MemoryStatsControllerTest.java Fri Oct 26 13:13:42 2012 +0200 @@ -73,7 +73,7 @@ public class MemoryStatsControllerTest { - private List<Generation> generations = new ArrayList<>(); + private Generation[] generations = new Generation[2]; private VmMemoryStatDAO memoryStatDao; private MemoryStatsView view; @@ -101,27 +101,29 @@ for (int i = 0; i < 2; i++) { Generation generation = new Generation(); - generation.name = "fluff" + i; - generation.spaces = new ArrayList<>(); + generation.setName("fluff" + i); + VmMemoryStat.Space[] spaces = new VmMemoryStat.Space[2 + (1 - i)]; for (int j = 0; j < 2; j++) { Space space = new Space(); - space.name = "fluffer" + i + j; - space.used = 100; - space.capacity = 1000; - space.maxCapacity = 10000; - - generation.spaces.add(space); + space.setName("fluffer" + i + j); + space.setUsed(100); + space.setCapacity(1000); + space.setMaxCapacity(10000); + spaces[j] = space; } - generations.add(generation); + if (i == 0) { + // special payload because the others have all the same values + canary = new Space(); + canary.setName("canary"); + canary.setUsed(1); + canary.setCapacity(2); + canary.setMaxCapacity(3); + spaces[2] = canary; + } + generation.setSpaces(spaces); + generations[i] = generation; } - // special payload because the others have all the same values - canary = new Space(); - canary.name = "canary"; - canary.used = 1; - canary.capacity = 2; - canary.maxCapacity = 3; - long timestamp = 1; int vmID = 1; for (int i = 0; i < 5; i++) { @@ -129,8 +131,6 @@ vmInfo.add(vmMemory); } - generations.get(0).spaces.add(canary); - memoryStatDao = mock(VmMemoryStatDAO.class); when(memoryStatDao.getLatestVmMemoryStats(any(VmRef.class), anyLong())).thenReturn(vmInfo); @@ -213,15 +213,15 @@ final long DATA_TIMESTAMP = System.currentTimeMillis() + 1000000000; Space space = new Space(); - space.capacity = 10; - space.maxCapacity = 20; - space.used = 5; + space.setCapacity(10); + space.setMaxCapacity(20); + space.setUsed(5); Generation gen = new Generation(); - gen.name = "foobar"; - gen.spaces = Arrays.asList(space); + gen.setName("foobar"); + gen.setSpaces(new Space[] { space }); VmMemoryStat stat = new VmMemoryStat(); stat.setTimeStamp(DATA_TIMESTAMP); - stat.setGenerations(Arrays.asList(gen)); + stat.setGenerations(new Generation[] { gen }); when(memoryStatDao.getLatestVmMemoryStats(isA(VmRef.class), anyLong())).thenReturn(Arrays.asList(stat));
--- a/common/core/src/main/java/com/redhat/thermostat/common/dao/Converter.java Fri Oct 26 13:12:46 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +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.Pojo; -import com.redhat.thermostat.common.storage.Chunk; - -public interface Converter<T extends Pojo> { - - Chunk toChunk(T pojo); - - T fromChunk(Chunk chunk); -}
--- a/common/core/src/main/java/com/redhat/thermostat/common/dao/VmMemoryStatConverter.java Fri Oct 26 13:12:46 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,184 +0,0 @@ -/* - * Copyright 2012 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <http://www.gnu.org/licenses/>. - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.common.dao; - -import java.util.ArrayList; -import java.util.List; - -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.Key; - -public class VmMemoryStatConverter implements Converter<VmMemoryStat> { - - @Override - public Chunk toChunk(VmMemoryStat vmMemStat) { - Chunk chunk = new Chunk(VmMemoryStatDAO.vmMemoryStatsCategory, false); - - chunk.put(Key.AGENT_ID, vmMemStat.getAgentId()); - chunk.put(Key.VM_ID, vmMemStat.getVmId()); - chunk.put(Key.TIMESTAMP, vmMemStat.getTimeStamp()); - - Generation newGen = vmMemStat.getGeneration("new"); - - Space eden = newGen.getSpace("eden"); - chunk.put(VmMemoryStatDAO.edenGenKey, newGen.name); - chunk.put(VmMemoryStatDAO.edenCollectorKey, newGen.collector); - chunk.put(VmMemoryStatDAO.edenCapacityKey, eden.capacity); - chunk.put(VmMemoryStatDAO.edenMaxCapacityKey, eden.maxCapacity); - chunk.put(VmMemoryStatDAO.edenUsedKey, eden.used); - - Space s0 = newGen.getSpace("s0"); - chunk.put(VmMemoryStatDAO.s0GenKey, newGen.name); - chunk.put(VmMemoryStatDAO.s0CollectorKey, newGen.collector); - chunk.put(VmMemoryStatDAO.s0CapacityKey, s0.capacity); - chunk.put(VmMemoryStatDAO.s0MaxCapacityKey, s0.maxCapacity); - chunk.put(VmMemoryStatDAO.s0UsedKey, s0.used); - - Space s1 = newGen.getSpace("s1"); - chunk.put(VmMemoryStatDAO.s1GenKey, newGen.name); - chunk.put(VmMemoryStatDAO.s1CollectorKey, newGen.collector); - chunk.put(VmMemoryStatDAO.s1CapacityKey, s1.capacity); - chunk.put(VmMemoryStatDAO.s1MaxCapacityKey, s1.maxCapacity); - chunk.put(VmMemoryStatDAO.s1UsedKey, s1.used); - - Generation oldGen = vmMemStat.getGeneration("old"); - - Space old = oldGen.getSpace("old"); - chunk.put(VmMemoryStatDAO.oldGenKey, oldGen.name); - chunk.put(VmMemoryStatDAO.oldCollectorKey, oldGen.collector); - chunk.put(VmMemoryStatDAO.oldCapacityKey, old.capacity); - chunk.put(VmMemoryStatDAO.oldMaxCapacityKey, old.maxCapacity); - chunk.put(VmMemoryStatDAO.oldUsedKey, old.used); - - Generation permGen = vmMemStat.getGeneration("perm"); - - Space perm = permGen.getSpace("perm"); - chunk.put(VmMemoryStatDAO.permGenKey, permGen.name); - chunk.put(VmMemoryStatDAO.permCollectorKey, permGen.collector); - chunk.put(VmMemoryStatDAO.permCapacityKey, perm.capacity); - chunk.put(VmMemoryStatDAO.permMaxCapacityKey, perm.maxCapacity); - chunk.put(VmMemoryStatDAO.permUsedKey, perm.used); - - return chunk; - } - - @Override - public VmMemoryStat fromChunk(Chunk chunk) { - Space space = null; - List<Space> spaces = null; - - List<Generation> gens = new ArrayList<>(); - Generation newGen = new Generation(); - spaces = new ArrayList<>(); - newGen.spaces = spaces; - newGen.name = "new"; - newGen.capacity = 0; - newGen.maxCapacity = 0; - // FIXME Something is wrong here when we have the collector stored - // as part of 3 spaces in Chunk but is only one thing in Stat - newGen.collector = chunk.get(VmMemoryStatDAO.edenCollectorKey); - - space = new Space(); - space.name = VmMemoryStatDAO.edenKey.getName(); - space.capacity = chunk.get(VmMemoryStatDAO.edenCapacityKey); - space.maxCapacity = chunk.get(VmMemoryStatDAO.edenMaxCapacityKey); - space.used = chunk.get(VmMemoryStatDAO.edenUsedKey); - spaces.add(space); - newGen.capacity += space.capacity; - newGen.maxCapacity += space.maxCapacity; - - space = new Space(); - space.name = VmMemoryStatDAO.s0Key.getName(); - space.capacity = chunk.get(VmMemoryStatDAO.s0CapacityKey); - space.maxCapacity = chunk.get(VmMemoryStatDAO.s0MaxCapacityKey); - space.used = chunk.get(VmMemoryStatDAO.s0UsedKey); - spaces.add(space); - newGen.capacity += space.capacity; - newGen.maxCapacity += space.maxCapacity; - - space = new Space(); - space.name = VmMemoryStatDAO.s1Key.getName(); - space.capacity = chunk.get(VmMemoryStatDAO.s1CapacityKey); - space.maxCapacity = chunk.get(VmMemoryStatDAO.s1MaxCapacityKey); - space.used = chunk.get(VmMemoryStatDAO.s1UsedKey); - spaces.add(space); - newGen.capacity += space.capacity; - newGen.maxCapacity += space.maxCapacity; - - gens.add(newGen); - - Generation oldGen = new Generation(); - spaces = new ArrayList<>(); - oldGen.spaces = spaces; - oldGen.name = "old"; - oldGen.collector = chunk.get(VmMemoryStatDAO.oldCollectorKey); - - space = new Space(); - space.name = VmMemoryStatDAO.oldKey.getName(); - space.capacity = chunk.get(VmMemoryStatDAO.oldCapacityKey); - space.maxCapacity = chunk.get(VmMemoryStatDAO.oldMaxCapacityKey); - space.used = chunk.get(VmMemoryStatDAO.oldUsedKey); - spaces.add(space); - oldGen.capacity = space.capacity; - oldGen.maxCapacity = space.capacity; - - gens.add(oldGen); - - Generation permGen = new Generation(); - spaces = new ArrayList<>(); - permGen.spaces = spaces; - permGen.name = "perm"; - permGen.collector = chunk.get(VmMemoryStatDAO.permCollectorKey); - - space = new Space(); - space.name = VmMemoryStatDAO.permKey.getName(); - space.capacity = chunk.get(VmMemoryStatDAO.permCapacityKey); - space.maxCapacity = chunk.get(VmMemoryStatDAO.permMaxCapacityKey); - space.used = chunk.get(VmMemoryStatDAO.permUsedKey); - spaces.add(space); - permGen.capacity = space.capacity; - permGen.maxCapacity = space.capacity; - - gens.add(permGen); - VmMemoryStat stat = new VmMemoryStat(chunk.get(Key.TIMESTAMP), chunk.get(Key.VM_ID), gens); - stat.setAgentId(chunk.get(Key.AGENT_ID)); - return stat; - } -}
--- a/common/core/src/main/java/com/redhat/thermostat/common/dao/VmMemoryStatDAO.java Fri Oct 26 13:12:46 2012 +0200 +++ b/common/core/src/main/java/com/redhat/thermostat/common/dao/VmMemoryStatDAO.java Fri Oct 26 13:13:42 2012 +0200 @@ -39,58 +39,16 @@ import java.util.List; import com.redhat.thermostat.common.model.VmMemoryStat; +import com.redhat.thermostat.common.model.VmMemoryStat.Generation; import com.redhat.thermostat.common.storage.Category; import com.redhat.thermostat.common.storage.Key; public interface VmMemoryStatDAO { - static final Key<String> edenKey = new Key<>("eden", false); - static final Key<String> edenGenKey = new Key<>("eden.gen", false); - static final Key<String> edenCollectorKey = new Key<>("eden.collector", false); - static final Key<Long> edenCapacityKey = new Key<>("eden.capacity", false); - static final Key<Long> edenMaxCapacityKey = new Key<>("eden.max-capacity", false); - static final Key<Long> edenUsedKey = new Key<>("eden.used", false); - - static final Key<String> s0Key = new Key<>("s0", false); - static final Key<String> s0GenKey = new Key<>("s0.gen", false); - static final Key<String> s0CollectorKey = new Key<>("s0.collector", false); - static final Key<Long> s0CapacityKey = new Key<>("s0.capacity", false); - static final Key<Long> s0MaxCapacityKey = new Key<>("s0.max-capacity", false); - static final Key<Long> s0UsedKey = new Key<>("s0.used", false); - - static final Key<String> s1Key = new Key<>("s1", false); - static final Key<String> s1GenKey = new Key<>("s1.gen", false); - static final Key<String> s1CollectorKey = new Key<>("s1.collector", false); - static final Key<Long> s1CapacityKey = new Key<>("s1.capacity", false); - static final Key<Long> s1MaxCapacityKey = new Key<>("s1.max-capacity", false); - static final Key<Long> s1UsedKey = new Key<>("s1.used", false); - - static final Key<String> oldKey = new Key<>("old", false); - static final Key<String> oldGenKey = new Key<>("old.gen", false); - static final Key<String> oldCollectorKey = new Key<>("old.collector", false); - static final Key<Long> oldCapacityKey = new Key<>("old.capacity", false); - static final Key<Long> oldMaxCapacityKey = new Key<>("old.max-capacity", false); - static final Key<Long> oldUsedKey = new Key<>("old.used", false); - - static final Key<String> permKey = new Key<>("perm", false); - static final Key<String> permGenKey = new Key<>("perm.gen", false); - static final Key<String> permCollectorKey = new Key<>("perm.collector", false); - static final Key<Long> permCapacityKey = new Key<>("perm.capacity", false); - static final Key<Long> permMaxCapacityKey = new Key<>("perm.max-capacity", false); - static final Key<Long> permUsedKey = new Key<>("perm.used", false); + static final Key<Generation[]> generationsKey = new Key<>("generations", false); static final Category vmMemoryStatsCategory = new Category("vm-memory-stats", - Key.AGENT_ID, Key.VM_ID, Key.TIMESTAMP, - edenGenKey, edenCollectorKey, - edenCapacityKey, edenMaxCapacityKey,edenUsedKey, - s0GenKey, s0CollectorKey, s0CapacityKey, - s0MaxCapacityKey, s0UsedKey, - s1GenKey, s1CollectorKey, s1CapacityKey, - s1MaxCapacityKey, s1UsedKey, - oldGenKey, oldCollectorKey, oldCapacityKey, - oldMaxCapacityKey, oldUsedKey, - permGenKey, permCollectorKey, permCapacityKey, - permMaxCapacityKey, permUsedKey); + Key.AGENT_ID, Key.VM_ID, Key.TIMESTAMP, generationsKey); public VmMemoryStat getLatestMemoryStat(VmRef ref);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/core/src/main/java/com/redhat/thermostat/common/model/AgentIdPojo.java Fri Oct 26 13:13:42 2012 +0200 @@ -0,0 +1,44 @@ +/* + * 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.model; + +public interface AgentIdPojo extends Pojo { + + void setAgentId(String agentId); + String getAgentId(); +}
--- a/common/core/src/main/java/com/redhat/thermostat/common/model/BasePojo.java Fri Oct 26 13:12:46 2012 +0200 +++ b/common/core/src/main/java/com/redhat/thermostat/common/model/BasePojo.java Fri Oct 26 13:13:42 2012 +0200 @@ -41,7 +41,7 @@ import com.redhat.thermostat.common.storage.Persist; -public class BasePojo implements Pojo { +public class BasePojo implements AgentIdPojo { private String agentId;
--- a/common/core/src/main/java/com/redhat/thermostat/common/model/CpuStat.java Fri Oct 26 13:12:46 2012 +0200 +++ b/common/core/src/main/java/com/redhat/thermostat/common/model/CpuStat.java Fri Oct 26 13:13:42 2012 +0200 @@ -36,8 +36,6 @@ package com.redhat.thermostat.common.model; -import java.util.List; - import com.redhat.thermostat.common.storage.Entity; import com.redhat.thermostat.common.storage.Persist; @@ -47,24 +45,24 @@ public static final double INVALID_LOAD = Double.MIN_VALUE; private long timeStamp; - private List<Double> perProcessorUsage; + private double[] perProcessorUsage; public CpuStat() { this(-1, null); } - public CpuStat(long timestamp, List<Double> perProcessorUsage) { + public CpuStat(long timestamp, double[] perProcessorUsage) { this.timeStamp = timestamp; this.perProcessorUsage = perProcessorUsage; } @Persist - public List<Double> getPerProcessorUsage() { + public double[] getPerProcessorUsage() { return perProcessorUsage; } @Persist - public void setPerProcessorUsage(List<Double> perProcessorUsage) { + public void setPerProcessorUsage(double[] perProcessorUsage) { this.perProcessorUsage = perProcessorUsage; }
--- a/common/core/src/main/java/com/redhat/thermostat/common/model/Pojo.java Fri Oct 26 13:12:46 2012 +0200 +++ b/common/core/src/main/java/com/redhat/thermostat/common/model/Pojo.java Fri Oct 26 13:13:42 2012 +0200 @@ -39,9 +39,30 @@ /** * All data types should implement this empty interface, to support the * generalization of DAO code where possible. + * + * In order to enable fully automatic serialization and deserialization of + * data objects, an implementation of this interface needs to adhere to + * a certain set of rules, that essentially boil down to compliance with + * JavaBeans specification plus Thermostat's @Entity and @Persist annotation. + * In detail those rules are: + * + * - A Pojo class needs to be annotated with @Entity (in addition to it implementing + * Pojo). + * - Only properties will be (de-)serialized, other method or fields will not + * be looked at. + * - Properties that should be (de-)serialized need to be annotated with @Persist, + * both on the getter and the setter method. + * - Serializable properties need to either be of primitive type, or String or + * other Pojos or arrays (indexed properties) of those types. (The reason for supporting + * only arrays as opposed to collections is that arrays carry type information, + * while collections don't, due to type erasure in Java generics. The type information + * is needed in order to re-construct the objects when deserializing.) + * - The properties need to be of the same type that its signatures declare. Specifically, + * they must not be of a subclass of that type. The reason for that is that + * the type information of the signature is used in deserialization. This also implies + * that such properties cannot be of abstract types. + * */ public interface Pojo { - void setAgentId(String agentId); - String getAgentId(); }
--- a/common/core/src/main/java/com/redhat/thermostat/common/model/VmGcStat.java Fri Oct 26 13:12:46 2012 +0200 +++ b/common/core/src/main/java/com/redhat/thermostat/common/model/VmGcStat.java Fri Oct 26 13:13:42 2012 +0200 @@ -37,6 +37,7 @@ package com.redhat.thermostat.common.model; import com.redhat.thermostat.common.storage.Entity; +import com.redhat.thermostat.common.storage.Persist; @Entity public class VmGcStat extends BasePojo implements TimeStampedPojo { @@ -59,43 +60,53 @@ this.wallTime = wallTime; } + @Persist public int getVmId() { return vmId; } + @Persist public void setVmId(int vmId) { this.vmId = vmId; } + @Persist public String getCollectorName() { return collectorName; } + @Persist public void setCollectorName(String collectorName) { this.collectorName = collectorName; } + @Persist public long getRunCount() { return runCount; } + @Persist public void setRunCount(long runCount) { this.runCount = runCount; } + @Persist public long getWallTime() { return wallTime; } + @Persist public void setWallTime(long wallTime) { this.wallTime = wallTime; } @Override + @Persist public long getTimeStamp() { return timeStamp; } + @Persist public void setTimeStamp(long timeStamp) { this.timeStamp = timeStamp; }
--- a/common/core/src/main/java/com/redhat/thermostat/common/model/VmInfo.java Fri Oct 26 13:12:46 2012 +0200 +++ b/common/core/src/main/java/com/redhat/thermostat/common/model/VmInfo.java Fri Oct 26 13:13:42 2012 +0200 @@ -37,8 +37,8 @@ package com.redhat.thermostat.common.model; import java.util.HashMap; -import java.util.List; import java.util.Map; +import java.util.Set; import com.redhat.thermostat.common.storage.Entity; import com.redhat.thermostat.common.storage.Persist; @@ -46,6 +46,44 @@ @Entity public class VmInfo extends BasePojo { + @Entity + public static class KeyValuePair implements Pojo { + + private String key; + private String value; + + public KeyValuePair() { + this(null, null); + } + + public KeyValuePair(String key, String value) { + this.key = key; + this.value = value; + } + + @Persist + public String getKey() { + return key; + } + + @Persist + public void setKey(String key) { + this.key = key; + } + + @Persist + public String getValue() { + return value; + } + + @Persist + public void setValue(String value) { + this.value = value; + } + + + } + private int vmPid = 0; private long startTime = System.currentTimeMillis(); private long stopTime = Long.MIN_VALUE; @@ -59,7 +97,7 @@ private String vmArguments = "unknown"; private Map<String, String> properties = new HashMap<String, String>(); private Map<String, String> environment = new HashMap<String, String>(); - private List<String> loadedNativeLibraries; + private String[] loadedNativeLibraries; public VmInfo() { /* use defaults */ @@ -69,7 +107,7 @@ String javaVersion, String javaHome, String mainClass, String commandLine, String vmName, String vmInfo, String vmVersion, String vmArguments, - Map<String, String> properties, Map<String, String> environment, List<String> loadedNativeLibraries) { + Map<String, String> properties, Map<String, String> environment, String[] loadedNativeLibraries) { this.vmPid = vmPid; this.startTime = startTime; this.stopTime = stopTime; @@ -210,33 +248,74 @@ return getStartTimeStamp() > getStopTimeStamp(); } - @Persist public Map<String, String> getProperties() { return properties; } - @Persist public void setProperties(Map<String, String> properties) { this.properties = properties; } @Persist + public KeyValuePair[] getPropertiesAsArray() { + return getMapAsArray(properties); + } + + @Persist + public void setPropertiesAsArray(KeyValuePair[] properties) { + this.properties = getArrayAsMap(properties); + } + public Map<String, String> getEnvironment() { return environment; } - @Persist public void setEnvironment(Map<String, String> environment) { this.environment = environment; } @Persist - public List<String> getLoadedNativeLibraries() { + public KeyValuePair[] getEnvironmentAsArray() { + return getMapAsArray(environment); + } + + @Persist + public void setEnvironmentAsArray(KeyValuePair[] environment) { + this.environment = getArrayAsMap(environment); + } + + private KeyValuePair[] getMapAsArray(Map<String, String> map) { + if (map == null) { + return null; + } + Set<String> keys = map.keySet(); + KeyValuePair[] tuples = new KeyValuePair[keys.size()]; + int i = 0; + for (String key: keys) { + tuples[i] = new KeyValuePair(key, map.get(key)); + i++; + } + return tuples; + } + + private Map<String,String> getArrayAsMap(KeyValuePair[] tuples) { + if (tuples == null) { + return null; + } + Map<String,String> map = new HashMap<>(); + for (KeyValuePair tuple : tuples) { + map.put(tuple.getKey(), tuple.getValue()); + } + return map; + } + + @Persist + public String[] getLoadedNativeLibraries() { return loadedNativeLibraries; } @Persist - public void setLoadedNativeLibraries(List<String> loadedNativeLibraries) { + public void setLoadedNativeLibraries(String[] loadedNativeLibraries) { this.loadedNativeLibraries = loadedNativeLibraries; } }
--- a/common/core/src/main/java/com/redhat/thermostat/common/model/VmMemoryStat.java Fri Oct 26 13:12:46 2012 +0200 +++ b/common/core/src/main/java/com/redhat/thermostat/common/model/VmMemoryStat.java Fri Oct 26 13:13:42 2012 +0200 @@ -36,17 +36,70 @@ package com.redhat.thermostat.common.model; -import java.util.List; +import com.redhat.thermostat.common.storage.Entity; +import com.redhat.thermostat.common.storage.Persist; +@Entity public class VmMemoryStat extends BasePojo implements TimeStampedPojo { - public static class Generation { + @Entity + public static class Generation implements Pojo { public static final String COLLECTOR_NONE = "none"; - public String name; - public long capacity; - public long maxCapacity; - public List<Space> spaces; - public String collector; + private String name; + private long capacity; + private long maxCapacity; + private Space[] spaces; + private String collector; + + @Persist + public String getName() { + return name; + } + + @Persist + public void setName(String name) { + this.name = name; + } + + @Persist + public long getCapacity() { + return capacity; + } + + @Persist + public void setCapacity(long capacity) { + this.capacity = capacity; + } + + @Persist + public long getMaxCapacity() { + return maxCapacity; + } + + @Persist + public void setMaxCapacity(long maxCapacity) { + this.maxCapacity = maxCapacity; + } + + @Persist + public Space[] getSpaces() { + return spaces; + } + + @Persist + public void setSpaces(Space[] spaces) { + this.spaces = spaces; + } + + @Persist + public String getCollector() { + return collector; + } + + @Persist + public void setCollector(String collector) { + this.collector = collector; + } public Space getSpace(String string) { for (Space s : spaces) { @@ -58,15 +111,68 @@ } } - public static class Space { - public int index; - public String name; - public long capacity; - public long maxCapacity; - public long used; + @Entity + public static class Space implements Pojo { + + private int index; + private String name; + private long capacity; + private long maxCapacity; + private long used; + + @Persist + public int getIndex() { + return index; + } + + @Persist + public void setIndex(int index) { + this.index = index; + } + + @Persist + public String getName() { + return name; + } + + @Persist + public void setName(String name) { + this.name = name; + } + + @Persist + public long getCapacity() { + return capacity; + } + + @Persist + public void setCapacity(long capacity) { + this.capacity = capacity; + } + + @Persist + public long getMaxCapacity() { + return maxCapacity; + } + + @Persist + public void setMaxCapacity(long maxCapacity) { + this.maxCapacity = maxCapacity; + } + + @Persist + public long getUsed() { + return used; + } + + @Persist + public void setUsed(long used) { + this.used = used; + } + } - private List<Generation> generations; + private Generation[] generations; private long timestamp; private int vmId; @@ -74,34 +180,42 @@ this(-1, -1, null); } - public VmMemoryStat(long timestamp, int vmId, List<Generation> generations) { + public VmMemoryStat(long timestamp, int vmId, Generation[] generations) { this.timestamp = timestamp; this.vmId = vmId; - this.generations = generations; + if (generations != null) { + this.generations = generations; + } } + @Persist public int getVmId() { return vmId; } + @Persist public void setVmId(int vmId) { this.vmId = vmId; } + @Persist @Override public long getTimeStamp() { return timestamp; } + @Persist public void setTimeStamp(long timeStamp) { this.timestamp = timeStamp; } - public List<Generation> getGenerations() { + @Persist + public Generation[] getGenerations() { return generations; } - public void setGenerations(List<Generation> generations) { + @Persist + public void setGenerations(Generation[] generations) { this.generations = generations; }
--- a/common/core/src/main/java/com/redhat/thermostat/common/storage/Chunk.java Fri Oct 26 13:12:46 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,109 +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.storage; - -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Objects; -import java.util.Set; - -/** - * A Chunk is a unit containing a set of data that can be added as a whole to the dataset - * that exists behind the storage layer. - */ -public class Chunk { - protected final boolean replace; - - protected Category category; - - private Map<Key<?>, Object> values = new LinkedHashMap<Key<?>, Object>(); - - protected Chunk() { - // FIXME this replace is wrong. it depends on the type of data we are interested in - replace = false; - } - - /** - * - * @param category The {@link Category} of this data. This should be a Category that the {@link Backend} - * who is producing this Chunk has registered via {@link Storage#registerCategory()} - * @param replace whether this chunk should replace the values based on the keys for this category, - * or be added to a set of values in this category - */ - public Chunk(Category category, boolean replace) { - // FIXME the insertion behaviour should not be part of the data structure itself - this.category = category; - this.replace = replace; - } - - public Category getCategory() { - return category; - } - - public boolean getReplace() { - return replace; - } - - public <T> void put(Key<T> entry, T value) { - values.put(entry, value); - } - - @SuppressWarnings("unchecked") - public <T> T get(Key<T> entry) { - // We only allow matching types in put(), so this cast should be fine. - return (T) values.get(entry); - } - - public Set<Key<?>> getKeys() { - return values.keySet(); - } - - @Override - public boolean equals(Object o) { - if (! (o instanceof Chunk)) { - return false; - } - Chunk other = (Chunk) o; - return Objects.equals(this.category, other.category) && Objects.equals(this.values, other.values); - } - - @Override - public String toString() { - return "Chunk: " + category.getName() + values.toString(); - } - -}
--- a/common/core/src/main/java/com/redhat/thermostat/common/storage/ChunkAdapter.java Fri Oct 26 13:12:46 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,191 +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.storage; - -import java.beans.PropertyDescriptor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.HashSet; -import java.util.Set; - -import org.apache.commons.beanutils.BeanUtils; -import org.apache.commons.beanutils.PropertyUtils; - -/** - * Adapts a bean into a Chunk. The bean must be annotated with {@link Entity}. - * All methods to persist must be annotated with {@link Persist} - */ -public class ChunkAdapter extends Chunk { - - private final Object adaptee; - - public ChunkAdapter(Object obj) { - this(obj, null, false); - Set<Key<?>> keys = identifyKeys(obj); - category = createCategory(obj, keys); - } - - public ChunkAdapter(Object obj, Category category, boolean replace) { - super(category, replace); - checkForAnnotation(obj); - adaptee = obj; - } - - public Object getAdaptee() { - return adaptee; - } - - private void checkForAnnotation(Object toCheck) { - if (!toCheck.getClass().isAnnotationPresent(Entity.class)) { - throw new IllegalArgumentException("object to adapt must be annotated with Entity"); - } - } - - private Set<Key<?>> identifyKeys(Object obj) { - Set<Key<?>> keys = new HashSet<>(); - - PropertyDescriptor[] descriptors = PropertyUtils.getPropertyDescriptors(obj); - for (PropertyDescriptor descriptor : descriptors) { - if (hasValidGetAndSetMethods(descriptor)) { - // FIXME this is sometimes a partial key - Key<?> key = new Key<>(findKeyName(descriptor), false); - keys.add(key); - } - } - return keys; - } - - private boolean hasValidGetAndSetMethods(PropertyDescriptor descriptor) { - Method readMethod = descriptor.getReadMethod(); - Method writeMethod = descriptor.getWriteMethod(); - - if (readMethod != null && writeMethod != null) { - if (readMethod.isAnnotationPresent(Persist.class) && - writeMethod.isAnnotationPresent(Persist.class)) { - return true; - } else if (readMethod.isAnnotationPresent(Persist.class) ^ - writeMethod.isAnnotationPresent(Persist.class)) { - throw new IllegalArgumentException("annotation only present on one of get/set method"); - } - } - return false; - } - - private String findKeyName(PropertyDescriptor descriptor) { - final String NAME_UNSPECIFIED = ""; - - String computedName = descriptor.getName(); - String nameOnGetMethod = descriptor.getReadMethod().getAnnotation(Persist.class).name(); - String nameOnSetMethod = descriptor.getWriteMethod().getAnnotation(Persist.class).name(); - - String attributeName; - if (nameOnGetMethod.equals(NAME_UNSPECIFIED) && nameOnSetMethod.equals(NAME_UNSPECIFIED)) { - attributeName = computedName; - } else { - if (!nameOnGetMethod.equals(nameOnSetMethod) && nameOnSetMethod.equals(NAME_UNSPECIFIED)) { - attributeName = nameOnGetMethod; - } else if (!nameOnSetMethod.equals(nameOnGetMethod) && nameOnGetMethod.equals(NAME_UNSPECIFIED)) { - attributeName = nameOnSetMethod; - } else { - throw new IllegalArgumentException("set/get methods have mismatching names in annotation"); - } - } - - return attributeName; - } - - private Category createCategory(Object obj, Set<Key<?>> keys) { - String newCategoryName = findCategoryName(obj); - Category category; - if (Categories.contains(newCategoryName)) { - Set<Key<?>> existingKeys= new HashSet<>(Categories.getByName(newCategoryName).getKeys()); - if (!keys.equals(existingKeys)) { - throw new IllegalArgumentException("this class, with a differet organization was seen previously"); - } - category = Categories.getByName(newCategoryName); - } else { - category = new Category(newCategoryName, keys.toArray(new Key<?>[0])); - } - return category; - } - - private String findCategoryName(Object obj) { - Entity categoryAnnotation = obj.getClass().getAnnotation(Entity.class); - String desiredName = categoryAnnotation.name(); - if (desiredName.equals("")) { - desiredName = obj.getClass().getSimpleName(); - } - return desiredName; - } - - @Override - public <T> T get(Key<T> entry) { - try { - return (T) PropertyUtils.getProperty(adaptee, entry.getName()); - } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { - e.printStackTrace(); - try { - System.err.println(BeanUtils.describe(adaptee)); - } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e1) { - e1.printStackTrace(); - } - } - return null; - } - - @Override - public <T> void put(Key<T> entry, T value) { - String keyName = entry.getName(); - try { - BeanUtils.setProperty(adaptee, keyName, value); - } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { - e.printStackTrace(); - try { - System.err.println(BeanUtils.describe(adaptee)); - } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e1) { - e1.printStackTrace(); - } - } - } - - @Override - public Set<Key<?>> getKeys() { - Category category = getCategory(); - return new HashSet<>(category.getKeys()); - } - -}
--- a/common/core/src/main/java/com/redhat/thermostat/common/storage/ChunkConverter.java Fri Oct 26 13:12:46 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,153 +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.storage; - -import java.util.HashMap; -import java.util.Map; -import java.util.logging.Logger; - -import org.bson.types.ObjectId; - -import com.mongodb.BasicDBList; -import com.mongodb.BasicDBObject; -import com.mongodb.DBObject; -import com.redhat.thermostat.common.utils.LoggingUtils; - -class ChunkConverter { - - private static final Logger logger = LoggingUtils.getLogger(ChunkConverter.class); - - DBObject chunkToDBObject(Chunk chunk) { - BasicDBObject dbObject = new BasicDBObject(); - Map<String, DBObject> dbObjectMap = null; - for (Key<?> key : chunk.getKeys()) { - dbObjectMap = convertChunkKey(chunk, key, dbObject, dbObjectMap); - } - return dbObject; - } - - private Map<String, DBObject> convertChunkKey(Chunk chunk, Key<?> key, DBObject dbObject, Map<String,DBObject> dbObjectMap) { - String[] keyParts = key.getName().split("\\."); - String initialName = keyParts[0]; - return convertChunkKeyRecursively(chunk, key, dbObject, keyParts, 0, initialName, dbObjectMap); - } - - private Map<String, DBObject> convertChunkKeyRecursively(Chunk chunk, Key<?> key, DBObject dbObject, String[] keyParts, int partIndex, - String partialKeyName, Map<String, DBObject> dbObjectMap) { - if (partIndex == keyParts.length - 1) { - String dbKey = keyParts[partIndex]; - Object value = chunk.get(key); - if (dbKey.equals("_id")) { - value = new ObjectId((String) value); - } - dbObject.put(dbKey, value); - } else { - dbObjectMap = lazyCreateDBObjectMap(dbObjectMap); - DBObject nestedDbObject = getOrCreateSubObject(partialKeyName, dbObjectMap); - dbObject.put(keyParts[partIndex], nestedDbObject); - partIndex++; - String nextSubKey = keyParts[partIndex]; - partialKeyName = partialKeyName + "." + nextSubKey; - convertChunkKeyRecursively(chunk, key, nestedDbObject, keyParts, partIndex, partialKeyName, dbObjectMap); - } - return dbObjectMap; - } - - - private Map<String, DBObject> lazyCreateDBObjectMap(Map<String, DBObject> dbObjectMap) { - if (dbObjectMap == null) { - dbObjectMap = new HashMap<String, DBObject>(); - } - return dbObjectMap; - } - - private DBObject getOrCreateSubObject(String partialKeyName, - Map<String, DBObject> dbObjectMap) { - DBObject dbObject = dbObjectMap.get(partialKeyName); - if (dbObject == null) { - dbObject = new BasicDBObject(); - dbObjectMap.put(partialKeyName, dbObject); - } - return dbObject; - } - - public Chunk dbObjectToChunk(DBObject dbObject, Category category) { - Chunk chunk = new Chunk(category, false); - dbObjectToChunkRecurse(chunk, dbObject, category, null); - return chunk; - } - - private void dbObjectToChunkRecurse(Chunk chunk, DBObject dbObject, Category category, String fullKey) { - for (String dbKey : dbObject.keySet()) { - String newFullKey; - if (fullKey == null) { - newFullKey = dbKey; - } else { - newFullKey = fullKey + "." + dbKey; - } - dbObjectToChunkRecursively(chunk, dbObject, category, dbKey, - newFullKey); - } - } - - private void dbObjectToChunkRecursively(Chunk chunk, DBObject dbObject, Category category, String dbKey, String fullKey) { - Object value = dbObject.get(dbKey); - Key key = category.getKey(fullKey); - if (value instanceof BasicDBList) { - if (key != null) { - chunk.put(key, value); - } else { - logger.warning("No key matching \"" + fullKey + "\" in category \"" + category + "\""); - } - } else if (value instanceof DBObject) { - DBObject dbObj = (DBObject) value; - dbObjectToChunkRecurse(chunk, dbObj, category, fullKey); - } else if (value instanceof ObjectId) { - chunk.put(key, objectIdToString((ObjectId) value)); - } else { - if (key != null) { - chunk.put(key, value); - } else { - logger.warning("No key matching \"" + fullKey + "\" in category \"" + category + "\""); - } - } - } - - private String objectIdToString(ObjectId value) { - return value.toString(); - } -}
--- a/common/core/src/main/java/com/redhat/thermostat/common/storage/ChunkToPojoConverter.java Fri Oct 26 13:12:46 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +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.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/MongoCursor.java Fri Oct 26 13:12:46 2012 +0200 +++ b/common/core/src/main/java/com/redhat/thermostat/common/storage/MongoCursor.java Fri Oct 26 13:13:42 2012 +0200 @@ -36,26 +36,18 @@ 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<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, Class<T> resultClass, Map<Class<?>, Converter<?>> converters) { + MongoCursor(DBCursor cursor, Class<T> resultClass) { this.cursor = cursor; - this.category = category; this.resultClass = resultClass; - this.converters = converters; } @Override @@ -69,9 +61,8 @@ if (next == null) { return null; } - ChunkConverter converter = new ChunkConverter(); - Chunk resultChunk = converter.dbObjectToChunk(next, category); - return ChunkToPojoConverter.convertChunkToPojo(resultChunk, resultClass, converters); + MongoPojoConverter converter = new MongoPojoConverter(); + return converter.convertMongoToPojo(next, resultClass); } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/core/src/main/java/com/redhat/thermostat/common/storage/MongoPojoConverter.java Fri Oct 26 13:13:42 2012 +0200 @@ -0,0 +1,164 @@ +/* + * 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.beans.PropertyDescriptor; +import java.lang.reflect.Array; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import org.apache.commons.beanutils.PropertyUtils; + +import com.mongodb.BasicDBObject; +import com.mongodb.DBObject; +import com.redhat.thermostat.common.model.Pojo; + +class MongoPojoConverter { + + public DBObject convertPojoToMongo(Pojo obj) { + try { + return convertPojoToMongoImpl(obj); + } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException ex) { + throw new StorageException(ex); + } + } + + private DBObject convertPojoToMongoImpl(Pojo obj) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { + BasicDBObject dbObj = new BasicDBObject(); + PropertyDescriptor[] descs = PropertyUtils.getPropertyDescriptors(obj); + for (PropertyDescriptor desc : descs) { + storePropertyToDBObject(obj, dbObj, desc); + } + return dbObj; + } + + private void storePropertyToDBObject(Pojo obj, BasicDBObject dbObj, PropertyDescriptor desc) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { + if (hasPersistentAnnotation(desc)) { + String name = desc.getName(); + Object value = PropertyUtils.getProperty(obj, name); + if (desc.getPropertyType().isArray()) { + value = convertIndexedProperty(value); + } + if (value instanceof Pojo) { + value = convertPojoToMongoImpl((Pojo) value); + } + dbObj.put(name, value); + } + } + + private Object convertIndexedProperty(Object values) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { + int length = Array.getLength(values); + List list = new ArrayList(length); + for (int i = 0; i < length; i++) { + Object value = Array.get(values, i); + if (value instanceof Pojo) { + value = convertPojoToMongoImpl((Pojo) value); + } + list.add(value); + } + return list; + } + + public <T extends Pojo> T convertMongoToPojo(DBObject dbObj, Class<T> pojoClass) { + try { + return convertMongoToPojoImpl(dbObj, pojoClass); + } catch (IllegalAccessException | InstantiationException | InvocationTargetException | NoSuchMethodException ex) { + throw new StorageException(ex); + } + } + + private <T extends Pojo> T convertMongoToPojoImpl(DBObject dbObj, Class pojoClass) throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException { + if (dbObj == null) { + return null; + } + T pojo = (T) pojoClass.newInstance(); + Set<String> keys = dbObj.keySet(); + for (String name : keys) { + if (! name.equals("_id")) { + storePropertyToPojo(dbObj, pojo, name); + } + } + return pojo; + } + + private <T extends Pojo> void storePropertyToPojo(DBObject dbObj, T pojo, String name) + throws IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException { + + PropertyDescriptor desc = PropertyUtils.getPropertyDescriptor(pojo, name); + if (hasPersistentAnnotation(desc)) { + Object value = dbObj.get(name); + if (desc.getPropertyType().isArray()) { + value = convertIndexedPropertyFromMongo(desc, (List) value); + } + if (value instanceof DBObject) { + value = convertMongoToPojoImpl((DBObject) value, desc.getPropertyType()); + } + PropertyUtils.setProperty(pojo, name, value); + } else { + throw new StorageException("no available mapping for extra property: '" + name + "' in " + pojo.getClass().getName()); + } + } + + private Object convertIndexedPropertyFromMongo(PropertyDescriptor desc, List values) throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException { + Class componentType = desc.getPropertyType().getComponentType(); + Object array = Array.newInstance(componentType, values.size()); + int i = 0; + for (Object value : values) { + if (value instanceof DBObject) { + value = convertMongoToPojoImpl((DBObject) value, componentType); + } + Array.set(array, i, value); + i++; + } + return array; + } + + private boolean hasPersistentAnnotation(PropertyDescriptor desc) { + if (desc == null) { + return false; + } + Method writeMethod = desc.getWriteMethod(); + Method readMethod = desc.getReadMethod(); + return writeMethod != null && writeMethod.isAnnotationPresent(Persist.class) + && readMethod != null && readMethod.isAnnotationPresent(Persist.class); + } + +}
--- a/common/core/src/main/java/com/redhat/thermostat/common/storage/MongoRemove.java Fri Oct 26 13:12:46 2012 +0200 +++ b/common/core/src/main/java/com/redhat/thermostat/common/storage/MongoRemove.java Fri Oct 26 13:13:42 2012 +0200 @@ -37,29 +37,37 @@ package com.redhat.thermostat.common.storage; +import com.mongodb.BasicDBObject; +import com.mongodb.DBObject; + class MongoRemove implements Remove { - private Chunk query; + private Category category; + private DBObject query; @Override public Remove from(Category category) { if (query != null) { throw new IllegalStateException(); } - query = new Chunk(category, false); + this.category = category; return this; } + Category getCategory() { + return category; + } + @Override public <T> Remove where(Key<T> key, T value) { if (query == null) { - throw new IllegalStateException(); + query = new BasicDBObject(); } - query.put(key, value); + query.put(key.getName(), value); return this; } - Chunk getChunk() { + DBObject getQuery() { return query; }
--- a/common/core/src/main/java/com/redhat/thermostat/common/storage/MongoStorage.java Fri Oct 26 13:12:46 2012 +0200 +++ b/common/core/src/main/java/com/redhat/thermostat/common/storage/MongoStorage.java Fri Oct 26 13:13:42 2012 +0200 @@ -37,10 +37,10 @@ package com.redhat.thermostat.common.storage; import java.io.InputStream; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Map.Entry; import java.util.UUID; import com.mongodb.BasicDBObject; @@ -52,10 +52,8 @@ import com.mongodb.gridfs.GridFSDBFile; import com.mongodb.gridfs.GridFSInputFile; import com.redhat.thermostat.common.config.StartupConfiguration; -import com.redhat.thermostat.common.dao.Converter; -import com.redhat.thermostat.common.dao.VmMemoryStatConverter; +import com.redhat.thermostat.common.model.AgentIdPojo; import com.redhat.thermostat.common.model.Pojo; -import com.redhat.thermostat.common.model.VmMemoryStat; import com.redhat.thermostat.common.storage.AbstractQuery.Sort; import com.redhat.thermostat.common.storage.Connection.ConnectionListener; import com.redhat.thermostat.common.storage.Connection.ConnectionStatus; @@ -75,10 +73,7 @@ private UUID agentId; - private Map<Class<?>, Converter<?>> converters; - public MongoStorage(StartupConfiguration conf) { - setupConverters(); conn = new MongoConnection(conf); conn.addListener(new ConnectionListener() { @Override @@ -95,11 +90,6 @@ }); } - private void setupConverters() { - converters = new HashMap<>(); - converters.put(VmMemoryStat.class, new VmMemoryStatConverter()); - } - @Override public Connection getConnection() { return conn; @@ -115,82 +105,42 @@ return agentId.toString(); } - private BasicDBObject getAgentQueryKeyFromGlobalAgent() { + private String getAgentQueryKeyFromGlobalAgent() { if (agentId != null) { - return new BasicDBObject(Key.AGENT_ID.getName(), agentId.toString()); + return agentId.toString(); } else { return null; } } - private BasicDBObject getAgentQueryKeyFromChunkOrGlobalAgent(Chunk chunk) { - BasicDBObject queryKey = getAgentQueryKeyFromGlobalAgent(); + private String getAgentQueryKeyFromChunkOrGlobalAgent(AgentIdPojo pojo) { + String queryKey = getAgentQueryKeyFromGlobalAgent(); if (queryKey != null) { return queryKey; - } else if (chunk.get(Key.AGENT_ID) != null) { - return new BasicDBObject(Key.AGENT_ID.getName(), chunk.get(Key.AGENT_ID)); } else { - return new BasicDBObject(); + return pojo.getAgentId(); } } - // TODO: Make this private, and change the testcase to test putPojo() instead. - void putChunk(Chunk chunk) { - Category cat = chunk.getCategory(); + @Override + public void putPojo(Category cat, boolean replace, AgentIdPojo pojo) { DBCollection coll = getCachedCollection(cat); - BasicDBObject toInsert = getAgentQueryKeyFromChunkOrGlobalAgent(chunk); - BasicDBObject replaceKey = null; - boolean replace = chunk.getReplace(); - Map<String, BasicDBObject> nestedParts = new HashMap<String, BasicDBObject>(); - Map<String, BasicDBObject> replaceKeyNestedParts = null; + MongoPojoConverter converter = new MongoPojoConverter(); + DBObject toInsert = converter.convertPojoToMongo(pojo); + String agentId = getAgentQueryKeyFromChunkOrGlobalAgent(pojo); + toInsert.put(Key.AGENT_ID.getName(), agentId); if (replace) { - replaceKey = getAgentQueryKeyFromChunkOrGlobalAgent(chunk); - replaceKeyNestedParts = new HashMap<String, BasicDBObject>(); - } - for (Key<?> key : cat.getKeys()) { - boolean isKey = key.isPartialCategoryKey(); - String[] entryParts = key.getName().split("\\."); - if (entryParts.length == 2) { - BasicDBObject nested = nestedParts.get(entryParts[0]); - if (nested == null) { - if (isKey) { - throwMissingKey(key.getName(), chunk); - } - nested = new BasicDBObject(); - nestedParts.put(entryParts[0], nested); - } - nested.append(entryParts[1], chunk.get(key)); - if (replace && isKey) { - BasicDBObject replaceKeyNested = replaceKeyNestedParts.get(entryParts[0]); - if (replaceKeyNested == null) { - replaceKeyNested = new BasicDBObject(); - replaceKeyNestedParts.put(entryParts[0], replaceKeyNested); - } - replaceKeyNested.append(entryParts[1], replaceKeyNested); - } - } else { - /* we dont modify agent id, and it's already used as key in updateKey */ - if (!key.equals(Key.AGENT_ID)) { - String mongoKey = key.getName(); - Object value = chunk.get(key); - if ((value == null) && isKey) { - throwMissingKey(key.getName(), chunk); - } - toInsert.append(mongoKey, value); - if (replace && isKey) { - replaceKey.append(mongoKey, value); - } + // TODO: Split this part out into a separate method. It is a very bad practice to + // completely change the behaviour of a method based on a boolean flag. + DBObject query = new BasicDBObject(); + Collection<Key<?>> keys = cat.getKeys(); + for (Key<?> key : keys) { + if (key.isPartialCategoryKey()) { + String name = key.getName(); + query.put(name, toInsert.get(name)); } } - } - for (Entry<String, BasicDBObject> entry: nestedParts.entrySet()) { - toInsert.append(entry.getKey(), entry.getValue()); - } - if (replace) { - for (Entry<String, BasicDBObject> entry: replaceKeyNestedParts.entrySet()) { - replaceKey.append(entry.getKey(), entry.getValue()); - } - coll.update(replaceKey, toInsert, true, false); + coll.update(query, toInsert); } else { coll.insert(toInsert); } @@ -200,95 +150,27 @@ public void updatePojo(Update update) { assert update instanceof MongoUpdate; MongoUpdate mongoUpdate = (MongoUpdate) update; - Chunk chunk = mongoUpdate.getChunk(); - updateChunk(chunk); - } - - void updateChunk(Chunk chunk) { - Category cat = chunk.getCategory(); + Category cat = mongoUpdate.getCategory(); DBCollection coll = getCachedCollection(cat); - BasicDBObject toUpdate = new BasicDBObject(); - BasicDBObject updateKey = getAgentQueryKeyFromChunkOrGlobalAgent(chunk); - BasicDBObject setObj = null; - Map<String, BasicDBObject> nestedParts = new HashMap<String, BasicDBObject>(); - Map<String, BasicDBObject> updateKeyNestedParts = new HashMap<String, BasicDBObject>(); - for (Key<?> key : cat.getKeys()) { - boolean isKey = key.isPartialCategoryKey(); - String[] entryParts = key.getName().split("\\."); - if (entryParts.length == 2) { - BasicDBObject nested = nestedParts.get(entryParts[0]); - if (nested == null) { - if (isKey) { - throwMissingKey(key.getName(), chunk); - } - } else { - if (isKey) { - BasicDBObject updateKeyNested = updateKeyNestedParts.get(entryParts[0]); - if (updateKeyNested == null) { - updateKeyNested = new BasicDBObject(); - updateKeyNestedParts.put(entryParts[0], updateKeyNested); - } - updateKeyNested.append(entryParts[1], updateKeyNested); - } else { - if (setObj == null) { - setObj = new BasicDBObject(); - nested.append(SET_MODIFIER, setObj); - } - setObj.append(entryParts[1], chunk.get(key)); - } - } - } else { - String mongoKey = key.getName(); - /* we dont modify agent id, and it's already used as key in updateKey */ - if (!key.equals(Key.AGENT_ID)) { - Object value = chunk.get(key); - if (value == null) { - if (isKey) { - throwMissingKey(key.getName(), chunk); - } - } else { - if (isKey) { - updateKey.append(mongoKey, value); - } else { - if (setObj == null) { - setObj = new BasicDBObject(); - toUpdate.append(SET_MODIFIER, setObj); - } - setObj.append(mongoKey, value); - } - } - } - } - } - for (Entry<String, BasicDBObject> entry: nestedParts.entrySet()) { - toUpdate.append(entry.getKey(), entry.getValue()); - } - for (Entry<String, BasicDBObject> entry: updateKeyNestedParts.entrySet()) { - updateKey.append(entry.getKey(), entry.getValue()); - } - coll.update(updateKey, toUpdate); - } - - private void throwMissingKey(String keyName, Chunk chunk) { - throw new IllegalArgumentException("Attempt to insert chunk with incomplete partial key. Missing: '" + keyName + "' in " + chunk); + DBObject query = mongoUpdate.getQuery(); + DBObject values = mongoUpdate.getValues(); + coll.update(query, values); } @Override public void removePojo(Remove remove) { assert (remove instanceof MongoRemove); MongoRemove mongoRemove = (MongoRemove) remove; - Chunk query = mongoRemove.getChunk(); - Category category = query.getCategory(); + DBObject query = mongoRemove.getQuery(); + Category category = mongoRemove.getCategory(); DBCollection coll = getCachedCollection(category); - BasicDBObject toRemove = getAgentQueryKeyFromChunkOrGlobalAgent(query); - for (Key<?> key : category.getKeys()) { - if (key.isPartialCategoryKey()) { - toRemove.put(key.getName(), query.get(key)); - } + String agentId = getAgentQueryKeyFromGlobalAgent(); + if (agentId != null) { + query.put(Key.AGENT_ID.getName(), agentId); } - coll.remove(toRemove); + coll.remove(query); } private DBCollection getCachedCollection(Category category) { @@ -310,9 +192,10 @@ @Override public void purge() { - BasicDBObject deleteKey = getAgentQueryKeyFromGlobalAgent(); + String deleteKey = getAgentQueryKeyFromGlobalAgent(); + BasicDBObject query = new BasicDBObject(Key.AGENT_ID.getName(), deleteKey); for (DBCollection coll : collectionCache.values()) { - coll.remove(deleteKey); + coll.remove(query); } } @@ -358,7 +241,7 @@ dbCursor = coll.find(); } dbCursor = applySortAndLimit(mongoQuery, dbCursor); - return new MongoCursor<T>(dbCursor, mongoQuery.getCategory(), resultClass, converters); + return new MongoCursor<T>(dbCursor, resultClass); } private DBCursor applySortAndLimit(MongoQuery query, DBCursor dbCursor) { @@ -375,22 +258,14 @@ return dbCursor; } + @Override public <T extends Pojo> T findPojo(Query query, Class<T> resultClass) { - Chunk resultChunk = find(query); - if (resultChunk == null) { - return null; - } - return ChunkToPojoConverter.convertChunkToPojo(resultChunk, resultClass, converters); - } - - // TODO: Make this private, and change the testcase to test putPojo() instead. - Chunk find(Query query) { MongoQuery mongoQuery = checkAndCastQuery(query); DBCollection coll = getCachedCollection(mongoQuery.getCategory()); DBObject dbResult = coll.findOne(mongoQuery.getGeneratedQuery()); - ChunkConverter converter = new ChunkConverter(); - return dbResult == null ? null : converter.dbObjectToChunk(dbResult, mongoQuery.getCategory()); + MongoPojoConverter conv = new MongoPojoConverter(); + return conv.convertMongoToPojo(dbResult, resultClass); } private MongoQuery checkAndCastQuery(Query query) { @@ -429,21 +304,4 @@ } } - @Override - public void putPojo(Category category, boolean replace, Pojo pojo) { - Chunk chunk = convertPojoToChunk(category, replace, pojo); - putChunk(chunk); - } - - private Chunk convertPojoToChunk(Category category, boolean replace, Pojo pojo) { - Converter customConverter = converters.get(pojo.getClass()); - Chunk chunk; - if (customConverter != null) { - chunk = customConverter.toChunk(pojo); - } else { - chunk = new ChunkAdapter(pojo, category, replace); - } - return chunk; - } - }
--- a/common/core/src/main/java/com/redhat/thermostat/common/storage/MongoUpdate.java Fri Oct 26 13:12:46 2012 +0200 +++ b/common/core/src/main/java/com/redhat/thermostat/common/storage/MongoUpdate.java Fri Oct 26 13:13:42 2012 +0200 @@ -37,42 +37,54 @@ package com.redhat.thermostat.common.storage; +import com.mongodb.BasicDBObject; +import com.mongodb.DBObject; + // TODO: For now we utilize the Chunk based conversion, and rely on MongoStorage to // actually resolve the $set fields. Eventually, we want to convert to DBObject // directly, and take advantage of improved semantics of this class. class MongoUpdate implements Update { - private Chunk updateChunk; + private DBObject query; + private DBObject values; + private Category category; @Override public Update from(Category category) { - if (updateChunk != null) { + if (query != null || values != null) { throw new IllegalStateException(); } - updateChunk = new Chunk(category, false); + this.category = category; return this; } + Category getCategory() { + return category; + } + @Override public <T> Update where(Key<T> key, T value) { - if (updateChunk == null) { - throw new IllegalStateException(); + if (query == null) { + query = new BasicDBObject(); } - updateChunk.put(key, value); + query.put(key.getName(), value); return this; } + DBObject getQuery() { + return query; + } + @Override public <T> Update set(Key<T> key, T value) { - if (updateChunk == null) { - throw new IllegalStateException(); + if (values == null) { + values = new BasicDBObject(); } - updateChunk.put(key, value); + values.put(key.getName(), value); return this; } - Chunk getChunk() { - return updateChunk; + DBObject getValues() { + return new BasicDBObject("$set", values); } - }
--- a/common/core/src/main/java/com/redhat/thermostat/common/storage/Storage.java Fri Oct 26 13:12:46 2012 +0200 +++ b/common/core/src/main/java/com/redhat/thermostat/common/storage/Storage.java Fri Oct 26 13:13:42 2012 +0200 @@ -39,6 +39,7 @@ import java.io.InputStream; import java.util.UUID; +import com.redhat.thermostat.common.model.AgentIdPojo; import com.redhat.thermostat.common.model.Pojo; public abstract class Storage { @@ -51,7 +52,7 @@ public abstract Connection getConnection(); - public abstract void putPojo(Category category, boolean replace, Pojo pojo); + public abstract void putPojo(Category category, boolean replace, AgentIdPojo pojo); public abstract void updatePojo(Update update);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/core/src/main/java/com/redhat/thermostat/common/storage/StorageException.java Fri Oct 26 13:13:42 2012 +0200 @@ -0,0 +1,58 @@ +/* + * 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; + +@SuppressWarnings("serial") +public class StorageException extends RuntimeException { + + public StorageException() { + super(); + } + public StorageException(String message) { + super(message); + } + + public StorageException(Throwable cause) { + super(cause); + } + + public StorageException(String message, Throwable cause) { + super(message, cause); + } + +}
--- a/common/core/src/test/java/com/redhat/thermostat/common/dao/BackendInfoDAOTest.java Fri Oct 26 13:12:46 2012 +0200 +++ b/common/core/src/test/java/com/redhat/thermostat/common/dao/BackendInfoDAOTest.java Fri Oct 26 13:13:42 2012 +0200 @@ -38,9 +38,10 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.when; import java.util.Arrays; import java.util.Collection; @@ -52,11 +53,10 @@ import com.redhat.thermostat.common.model.BackendInformation; 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.QueryTestHelper; -import com.redhat.thermostat.common.storage.Query.Criteria; import com.redhat.thermostat.common.storage.Remove; import com.redhat.thermostat.common.storage.Storage; import com.redhat.thermostat.test.MockQuery;
--- a/common/core/src/test/java/com/redhat/thermostat/common/dao/CpuStatDAOTest.java Fri Oct 26 13:12:46 2012 +0200 +++ b/common/core/src/test/java/com/redhat/thermostat/common/dao/CpuStatDAOTest.java Fri Oct 26 13:13:42 2012 +0200 @@ -46,7 +46,6 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import java.util.Arrays; import java.util.Collection; import java.util.List; @@ -59,7 +58,6 @@ 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.utils.ArrayUtils; import com.redhat.thermostat.test.MockQuery; public class CpuStatDAOTest { @@ -86,8 +84,7 @@ CpuStatDAO dao = new CpuStatDAOImpl(storage); Double LOAD = 5.0; - List<Double> loadList = Arrays.asList(LOAD); - CpuStat cpuStat = new CpuStat(1234L, loadList); + CpuStat cpuStat = new CpuStat(1234L, new double[] { LOAD }); when(cursor.hasNext()).thenReturn(true).thenReturn(false); when(cursor.next()).thenReturn(cpuStat); @@ -103,7 +100,7 @@ assertEquals(1, cpuStats.size()); CpuStat stat = cpuStats.get(0); assertEquals(1234L, stat.getTimeStamp()); - assertArrayEquals(new double[] { LOAD }, ArrayUtils.toPrimitiveDoubleArray(stat.getPerProcessorUsage()), 0.001); + assertArrayEquals(new double[] { LOAD }, stat.getPerProcessorUsage(), 0.001); } @@ -118,7 +115,7 @@ CpuStatDAO dao = new CpuStatDAOImpl(storage); - CpuStat cpuStat = new CpuStat(1234L, Arrays.asList(5.0)); + CpuStat cpuStat = new CpuStat(1234L, new double[] { 5.0 }); when(cursor.hasNext()).thenReturn(true).thenReturn(false); when(cursor.next()).thenReturn(cpuStat); @@ -138,7 +135,7 @@ @Test public void testPutCpuStat() { Storage storage = mock(Storage.class); - CpuStat stat = new CpuStat(1, ArrayUtils.toDoubleList(new double[] {5.0, 10.0, 15.0})); + CpuStat stat = new CpuStat(1, new double[] {5.0, 10.0, 15.0}); CpuStatDAO dao = new CpuStatDAOImpl(storage); dao.putCpuStat(stat);
--- a/common/core/src/test/java/com/redhat/thermostat/common/dao/HostInfoDAOTest.java Fri Oct 26 13:12:46 2012 +0200 +++ b/common/core/src/test/java/com/redhat/thermostat/common/dao/HostInfoDAOTest.java Fri Oct 26 13:13:42 2012 +0200 @@ -56,7 +56,6 @@ import com.redhat.thermostat.common.model.AgentInformation; import com.redhat.thermostat.common.model.HostInfo; import com.redhat.thermostat.common.storage.Category; -import com.redhat.thermostat.common.storage.Chunk; import com.redhat.thermostat.common.storage.Cursor; import com.redhat.thermostat.common.storage.Key; import com.redhat.thermostat.common.storage.Query; @@ -99,14 +98,6 @@ @Test public void testGetHostInfo() { - Chunk chunk = new Chunk(HostInfoDAO.hostInfoCategory, false); - chunk.put(HostInfoDAO.hostNameKey, HOST_NAME); - chunk.put(HostInfoDAO.osNameKey, OS_NAME); - chunk.put(HostInfoDAO.osKernelKey, OS_KERNEL); - chunk.put(HostInfoDAO.cpuModelKey, CPU_MODEL); - chunk.put(HostInfoDAO.cpuCountKey, CPU_NUM); - chunk.put(HostInfoDAO.hostMemoryTotalKey, MEMORY_TOTAL); - Storage storage = mock(Storage.class); when(storage.createQuery()).thenReturn(new MockQuery()); HostInfo info = new HostInfo(HOST_NAME, OS_NAME, OS_KERNEL, CPU_MODEL, CPU_NUM, MEMORY_TOTAL); @@ -305,10 +296,6 @@ agentInfo2.setAgentId("456"); agentInfo2.setAlive(true); - Chunk agentConfig3 = new Chunk(AgentInfoDAO.CATEGORY, false); - agentConfig3.put(Key.AGENT_ID, "678"); - agentConfig3.put(AgentInfoDAO.ALIVE_KEY, true); - AgentInformation agentInfo3 = new AgentInformation(); agentInfo3.setAgentId("678"); agentInfo3.setAlive(true);
--- a/common/core/src/test/java/com/redhat/thermostat/common/dao/HostLatestPojoListGetterTest.java Fri Oct 26 13:12:46 2012 +0200 +++ b/common/core/src/test/java/com/redhat/thermostat/common/dao/HostLatestPojoListGetterTest.java Fri Oct 26 13:13:42 2012 +0200 @@ -43,7 +43,6 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import java.util.Arrays; import java.util.List; import org.junit.After; @@ -56,7 +55,6 @@ 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.utils.ArrayUtils; import com.redhat.thermostat.test.MockQuery; public class HostLatestPojoListGetterTest { @@ -89,9 +87,9 @@ @Before public void setUp() { ref = new HostRef(AGENT_ID, HOSTNAME); - 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)); + result1 = new CpuStat(t1, new double[] { load5_1, load10_1, load15_1 } ); + result2 = new CpuStat(t2, new double[] { load5_2, load10_2, load15_2 } ); + result3 = new CpuStat(t3, new double[] { load5_3, load10_3, load15_3 } ); } @Test @@ -152,10 +150,10 @@ assertEquals(2, stats.size()); CpuStat stat1 = stats.get(0); assertEquals(t1, stat1.getTimeStamp()); - assertArrayEquals(new double[] {load5_1, load10_1, load15_1}, ArrayUtils.toPrimitiveDoubleArray(stat1.getPerProcessorUsage()), 0.001); + assertArrayEquals(new double[] {load5_1, load10_1, load15_1}, stat1.getPerProcessorUsage(), 0.001); CpuStat stat2 = stats.get(1); assertEquals(t2, stat2.getTimeStamp()); - assertArrayEquals(new double[] {load5_2, load10_2, load15_2}, ArrayUtils.toPrimitiveDoubleArray(stat2.getPerProcessorUsage()), 0.001); + assertArrayEquals(new double[] {load5_2, load10_2, load15_2}, stat2.getPerProcessorUsage(), 0.001); } @After
--- a/common/core/src/test/java/com/redhat/thermostat/common/dao/VmInfoDAOTest.java Fri Oct 26 13:12:46 2012 +0200 +++ b/common/core/src/test/java/com/redhat/thermostat/common/dao/VmInfoDAOTest.java Fri Oct 26 13:13:42 2012 +0200 @@ -45,7 +45,6 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; -import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; @@ -56,12 +55,11 @@ import com.redhat.thermostat.common.model.VmInfo; import com.redhat.thermostat.common.storage.Category; -import com.redhat.thermostat.common.storage.Chunk; import com.redhat.thermostat.common.storage.Cursor; import com.redhat.thermostat.common.storage.Key; import com.redhat.thermostat.common.storage.Query; +import com.redhat.thermostat.common.storage.Query.Criteria; import com.redhat.thermostat.common.storage.QueryTestHelper; -import com.redhat.thermostat.common.storage.Query.Criteria; import com.redhat.thermostat.common.storage.Storage; import com.redhat.thermostat.common.storage.Update; import com.redhat.thermostat.test.MockQuery; @@ -81,7 +79,7 @@ private String vmArgs; private Map<String, String> props; private Map<String, String> env; - private List<String> libs; + private String[] libs; @Before public void setUp() { @@ -98,7 +96,7 @@ vmVersion = "1.0"; props = new HashMap<>(); env = new HashMap<>(); - libs = new ArrayList<>(); + libs = new String[0]; } @Test @@ -126,22 +124,6 @@ @Test public void testGetVmInfo() { - Chunk chunk = new Chunk(VmInfoDAO.vmInfoCategory, true); - chunk.put(Key.VM_ID, vmId); - chunk.put(VmInfoDAO.vmPidKey, vmId); - chunk.put(VmInfoDAO.startTimeKey, startTime); - chunk.put(VmInfoDAO.stopTimeKey, stopTime); - chunk.put(VmInfoDAO.runtimeVersionKey, jVersion); - chunk.put(VmInfoDAO.javaHomeKey, jHome); - chunk.put(VmInfoDAO.mainClassKey, mainClass); - chunk.put(VmInfoDAO.commandLineKey, commandLine); - chunk.put(VmInfoDAO.vmNameKey, vmName); - chunk.put(VmInfoDAO.vmInfoKey, vmInfo); - chunk.put(VmInfoDAO.vmVersionKey, vmVersion); - chunk.put(VmInfoDAO.vmArgumentsKey, vmArgs); - chunk.put(VmInfoDAO.propertiesKey, props); - chunk.put(VmInfoDAO.environmentKey, env); - chunk.put(VmInfoDAO.librariesKey, libs); Storage storage = mock(Storage.class); Query query = new MockQuery();
--- a/common/core/src/test/java/com/redhat/thermostat/common/dao/VmMemoryStatConverterTest.java Fri Oct 26 13:12:46 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,233 +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.ArrayList; -import java.util.List; - -import org.junit.Test; - -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.Key; - -public class VmMemoryStatConverterTest { - - @Test - public void testVmMemoryStatToChunk() { - List<Generation> generations = new ArrayList<Generation>(); - - int i = 0; - for (String genName: new String[] { "new", "old", "perm" }) { - Generation gen = new Generation(); - gen.name = genName; - gen.collector = gen.name; - generations.add(gen); - List<Space> spaces = new ArrayList<Space>(); - gen.spaces = spaces; - String[] spaceNames = null; - if (genName.equals("new")) { - spaceNames = new String[] { "eden", "s0", "s1" }; - } else if (genName.equals("old")) { - spaceNames = new String[] { "old" }; - } else { - spaceNames = new String[] { "perm" }; - } - for (String spaceName: spaceNames) { - Space space = new Space(); - space.name = spaceName; - space.index = 0; - space.used = i++; - space.capacity = i++; - space.maxCapacity = i++; - spaces.add(space); - } - } - - VmMemoryStat stat = new VmMemoryStat(1, 2, generations); - - Chunk chunk = new VmMemoryStatConverter().toChunk(stat); - - assertNotNull(chunk); - assertEquals((Long) 1l, chunk.get(new Key<Long>("timeStamp", false))); - assertEquals((Integer) 2, chunk.get(new Key<Integer>("vmId", true))); - assertEquals("new", chunk.get(new Key<String>("eden.gen", false))); - assertEquals("new", chunk.get(new Key<String>("eden.collector", false))); - assertEquals((Long) 0l, chunk.get(new Key<Long>("eden.used", false))); - assertEquals((Long) 1l, chunk.get(new Key<Long>("eden.capacity", false))); - assertEquals((Long) 2l, chunk.get(new Key<Long>("eden.max-capacity", false))); - assertEquals("new", chunk.get(new Key<String>("s0.gen", false))); - assertEquals("new", chunk.get(new Key<String>("s0.collector", false))); - assertEquals((Long) 3l, chunk.get(new Key<Long>("s0.used", false))); - assertEquals((Long) 4l, chunk.get(new Key<Long>("s0.capacity", false))); - assertEquals((Long) 5l, chunk.get(new Key<Long>("s0.max-capacity", false))); - assertEquals("new", chunk.get(new Key<String>("s1.gen", false))); - assertEquals("new", chunk.get(new Key<String>("s1.collector", false))); - assertEquals((Long) 6l, chunk.get(new Key<Long>("s1.used", false))); - assertEquals((Long) 7l, chunk.get(new Key<Long>("s1.capacity", false))); - assertEquals((Long) 8l, chunk.get(new Key<Long>("s1.max-capacity", false))); - assertEquals("old", chunk.get(new Key<String>("old.gen", false))); - assertEquals("old", chunk.get(new Key<String>("old.collector", false))); - assertEquals((Long) 9l, chunk.get(new Key<Long>("old.used", false))); - assertEquals((Long) 10l, chunk.get(new Key<Long>("old.capacity", false))); - assertEquals((Long) 11l, chunk.get(new Key<Long>("old.max-capacity", false))); - assertEquals("perm", chunk.get(new Key<String>("perm.gen", false))); - assertEquals("perm", chunk.get(new Key<String>("perm.collector", false))); - assertEquals((Long) 12l, chunk.get(new Key<Long>("perm.used", false))); - assertEquals((Long) 13l, chunk.get(new Key<Long>("perm.capacity", false))); - assertEquals((Long) 14l, chunk.get(new Key<Long>("perm.max-capacity", false))); - - } - - @Test - public void testChunkToVmMemoryStat() { - final long TIMESTAMP = 1234l; - final int VM_ID = 4567; - - final long EDEN_USED = 1; - final long EDEN_CAPACITY = 2; - final long EDEN_MAX_CAPACITY = 3; - - final long S0_USED = 4; - final long S0_CAPACITY = 5; - final long S0_MAX_CAPACITY = 6; - - final long S1_USED = 7; - final long S1_CAPACITY = 8; - final long S1_MAX_CAPACITY = 9; - - final long OLD_USED = 10; - final long OLD_CAPACITY = 11; - final long OLD_MAX_CAPACITY = 12; - - final long PERM_USED = 13; - final long PERM_CAPACITY = 14; - final long PERM_MAX_CAPACITY = 15; - - Chunk chunk = new Chunk(VmMemoryStatDAO.vmMemoryStatsCategory, false); - - chunk.put(Key.TIMESTAMP, TIMESTAMP); - chunk.put(Key.VM_ID, VM_ID); - - chunk.put(VmMemoryStatDAO.edenGenKey, "new"); - chunk.put(VmMemoryStatDAO.edenCollectorKey, "new-collector"); - chunk.put(VmMemoryStatDAO.edenUsedKey, EDEN_USED); - chunk.put(VmMemoryStatDAO.edenCapacityKey, EDEN_CAPACITY); - chunk.put(VmMemoryStatDAO.edenMaxCapacityKey, EDEN_MAX_CAPACITY); - - chunk.put(VmMemoryStatDAO.s0GenKey, "new"); - chunk.put(VmMemoryStatDAO.s0CollectorKey, "new-collector"); - chunk.put(VmMemoryStatDAO.s0UsedKey, S0_USED); - chunk.put(VmMemoryStatDAO.s0CapacityKey, S0_CAPACITY); - chunk.put(VmMemoryStatDAO.s0MaxCapacityKey, S0_MAX_CAPACITY); - - chunk.put(VmMemoryStatDAO.s1GenKey, "new"); - chunk.put(VmMemoryStatDAO.s1CollectorKey, "new-collector"); - chunk.put(VmMemoryStatDAO.s1UsedKey, S1_USED); - chunk.put(VmMemoryStatDAO.s1CapacityKey, S1_CAPACITY); - chunk.put(VmMemoryStatDAO.s1MaxCapacityKey, S1_MAX_CAPACITY); - - chunk.put(VmMemoryStatDAO.oldGenKey, "old"); - chunk.put(VmMemoryStatDAO.oldCollectorKey, "old-collector"); - chunk.put(VmMemoryStatDAO.oldUsedKey, OLD_USED); - chunk.put(VmMemoryStatDAO.oldCapacityKey, OLD_CAPACITY); - chunk.put(VmMemoryStatDAO.oldMaxCapacityKey, OLD_MAX_CAPACITY); - - chunk.put(VmMemoryStatDAO.permGenKey, "perm"); - chunk.put(VmMemoryStatDAO.permCollectorKey, "perm-collector"); - chunk.put(VmMemoryStatDAO.permUsedKey, PERM_USED); - chunk.put(VmMemoryStatDAO.permCapacityKey, PERM_CAPACITY); - chunk.put(VmMemoryStatDAO.permMaxCapacityKey, PERM_MAX_CAPACITY); - - VmMemoryStat stat = new VmMemoryStatConverter().fromChunk(chunk); - - assertNotNull(stat); - assertEquals(TIMESTAMP, stat.getTimeStamp()); - assertEquals(VM_ID, stat.getVmId()); - - assertEquals(3, stat.getGenerations().size()); - - Generation newGen = stat.getGeneration("new"); - assertNotNull(newGen); - assertEquals(3, newGen.spaces.size()); - assertEquals("new-collector", newGen.collector); - - Space eden = newGen.getSpace("eden"); - assertNotNull(eden); - assertEquals(EDEN_USED, eden.used); - assertEquals(EDEN_CAPACITY, eden.capacity); - assertEquals(EDEN_MAX_CAPACITY, eden.maxCapacity); - - Space s0 = newGen.getSpace("s0"); - assertNotNull(s0); - assertEquals(S0_USED, s0.used); - assertEquals(S0_CAPACITY, s0.capacity); - assertEquals(S0_MAX_CAPACITY, s0.maxCapacity); - - Space s1 = newGen.getSpace("s1"); - assertNotNull(s1); - assertEquals(S1_USED, s1.used); - assertEquals(S1_CAPACITY, s1.capacity); - assertEquals(S1_MAX_CAPACITY, s1.maxCapacity); - - Generation oldGen = stat.getGeneration("old"); - assertNotNull(oldGen); - assertEquals(1, oldGen.spaces.size()); - assertEquals("old-collector", oldGen.collector); - - Space old = oldGen.getSpace("old"); - assertNotNull(old); - assertEquals(OLD_USED, old.used); - assertEquals(OLD_CAPACITY, old.capacity); - assertEquals(OLD_MAX_CAPACITY, old.maxCapacity); - - Generation permGen = stat.getGeneration("perm"); - assertNotNull(permGen); - assertEquals(1, permGen.spaces.size()); - assertEquals("perm-collector", permGen.collector); - - Space permSpace = permGen.getSpace("perm"); - assertNotNull(permSpace); - assertEquals(PERM_USED, permSpace.used); - assertEquals(PERM_CAPACITY, permSpace.capacity); - assertEquals(PERM_MAX_CAPACITY, permSpace.maxCapacity); - } -}
--- a/common/core/src/test/java/com/redhat/thermostat/common/dao/VmMemoryStatDAOTest.java Fri Oct 26 13:12:46 2012 +0200 +++ b/common/core/src/test/java/com/redhat/thermostat/common/dao/VmMemoryStatDAOTest.java Fri Oct 26 13:13:42 2012 +0200 @@ -113,32 +113,8 @@ assertTrue(keys.contains(new Key<>("agentId", true))); assertTrue(keys.contains(new Key<Integer>("vmId", true))); assertTrue(keys.contains(new Key<Long>("timeStamp", false))); - assertTrue(keys.contains(new Key<String>("eden.gen", false))); - assertTrue(keys.contains(new Key<String>("eden.collector", false))); - assertTrue(keys.contains(new Key<Long>("eden.capacity", false))); - assertTrue(keys.contains(new Key<Long>("eden.max-capacity", false))); - assertTrue(keys.contains(new Key<Long>("eden.used", false))); - assertTrue(keys.contains(new Key<String>("s0.gen", false))); - assertTrue(keys.contains(new Key<String>("s0.collector", false))); - assertTrue(keys.contains(new Key<Long>("s0.capacity", false))); - assertTrue(keys.contains(new Key<Long>("s0.max-capacity", false))); - assertTrue(keys.contains(new Key<Long>("s0.used", false))); - assertTrue(keys.contains(new Key<String>("s1.gen", false))); - assertTrue(keys.contains(new Key<String>("s1.collector", false))); - assertTrue(keys.contains(new Key<Long>("s1.capacity", false))); - assertTrue(keys.contains(new Key<Long>("s1.max-capacity", false))); - assertTrue(keys.contains(new Key<Long>("s1.used", false))); - assertTrue(keys.contains(new Key<String>("old.gen", false))); - assertTrue(keys.contains(new Key<String>("old.collector", false))); - assertTrue(keys.contains(new Key<Long>("old.capacity", false))); - assertTrue(keys.contains(new Key<Long>("old.max-capacity", false))); - assertTrue(keys.contains(new Key<Long>("old.used", false))); - assertTrue(keys.contains(new Key<String>("perm.gen", false))); - assertTrue(keys.contains(new Key<String>("perm.collector", false))); - assertTrue(keys.contains(new Key<Long>("perm.capacity", false))); - assertTrue(keys.contains(new Key<Long>("perm.max-capacity", false))); - assertTrue(keys.contains(new Key<Long>("perm.used", false))); - assertEquals(28, keys.size()); + assertTrue(keys.contains(new Key<Generation[]>("generations", false))); + assertEquals(4, keys.size()); } @Test @@ -188,11 +164,10 @@ int i = 0; for (String genName: new String[] { "new", "old", "perm" }) { Generation gen = new Generation(); - gen.name = genName; - gen.collector = gen.name; + gen.setName(genName); + gen.setCollector(gen.getName()); generations.add(gen); List<Space> spaces = new ArrayList<Space>(); - gen.spaces = spaces; String[] spaceNames = null; if (genName.equals("new")) { spaceNames = new String[] { "eden", "s0", "s1" }; @@ -203,15 +178,16 @@ } for (String spaceName: spaceNames) { Space space = new Space(); - space.name = spaceName; - space.index = 0; - space.used = i++; - space.capacity = i++; - space.maxCapacity = i++; + space.setName(spaceName); + space.setIndex(0); + space.setUsed(i++); + space.setCapacity(i++); + space.setMaxCapacity(i++); spaces.add(space); } + gen.setSpaces(spaces.toArray(new Space[spaces.size()])); } - VmMemoryStat stat = new VmMemoryStat(1, 2, generations); + VmMemoryStat stat = new VmMemoryStat(1, 2, generations.toArray(new Generation[generations.size()])); Storage storage = mock(Storage.class); VmMemoryStatDAO dao = new VmMemoryStatDAOImpl(storage);
--- a/common/core/src/test/java/com/redhat/thermostat/common/storage/ChunkAdapterTest.java Fri Oct 26 13:12:46 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,319 +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.storage; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Set; - -import org.junit.Test; - -public class ChunkAdapterTest { - - @Entity - public static class SomeData { - - private long[] arrayData; - private List<String> listData; - private long longData; - private String stringData; - private NestedData nestedData; - - @Persist - public long[] getArrayData() { - return arrayData; - } - - @Persist - public void setArrayData(long[] arrayData) { - this.arrayData = arrayData; - } - - public void setListData(List<String> data) { - this.listData = data; - } - - public List<String> getListData() { - return listData; - } - - public long getLongData() { - return longData; - } - - public void setLongData(long newValue) { - longData = newValue; - } - - public void setStringData(String newStringData) { - stringData = newStringData; - } - - public String getStringData() { - return stringData; - } - - public NestedData getNestedData() { - return nestedData; - } - - public void setNestedData(NestedData nestedData) { - this.nestedData = nestedData; - } - } - - public static class NestedData { - private String data; - public void setData(String data) { - this.data = data; - } - public String getData() { - return data; - } - } - - // the expected keys for each 'property' in the SomeData bean - private static final Key<long[]> arrayData = new Key<>("arrayData", false); - private static final Key<List<String>> listData = new Key<>("listData", false); - private static final Key<Long> longData = new Key<>("longData", false); - private static final Key<String> stringData = new Key<>("stringData", false); - private static final Key<String> nestedData = new Key<>("nestedData.data", false); - - @Test - public void verifyAdapaterCanBeUsedInPlaceOfChunk() { - SomeData testObject = new SomeData(); - ChunkAdapter adapter = new ChunkAdapter(testObject); - - assertTrue(adapter instanceof Chunk); - } - - @Test - public void verifyCategoryName() { - SomeData testObject = new SomeData(); - ChunkAdapter adapter = new ChunkAdapter(testObject); - Category category = adapter.getCategory(); - assertNotNull(category); - assertEquals("SomeData", category.getName()); - } - - @Test - public void verifyKeys() throws InterruptedException { - SomeData testObject = new SomeData(); - Chunk chunk = new ChunkAdapter(testObject); - testObject.setArrayData(new long[] { 0xADD }); - - Set<Key<?>> recognizedKeys = chunk.getKeys(); - // only one method is annotated with @Persist - assertEquals(1, recognizedKeys.size()); - // verify that single key can be read - Key<?> onlyRecognizedKey = recognizedKeys.iterator().next(); - assertArrayEquals(new long[] { 0xADD }, (long[]) chunk.get(onlyRecognizedKey)); - } - - @Test - public void verifyGetAndPutLongValue() { - SomeData testObject = new SomeData(); - Chunk chunk = new ChunkAdapter(testObject); - testObject.setLongData(1l); - - assertEquals((Long) 1l, chunk.get(longData)); - - chunk.put(longData, 2l); - - assertEquals((Long) 2l, chunk.get(longData)); - assertEquals(2, testObject.longData); - } - - @Test - public void verifyGetAndPutStringValue() { - SomeData testObject = new SomeData(); - Chunk chunk = new ChunkAdapter(testObject); - testObject.setStringData("stringData"); - - assertEquals("stringData", chunk.get(stringData)); - - chunk.put(stringData, "some-new-data"); - - assertEquals("some-new-data", chunk.get(stringData)); - assertEquals("some-new-data", testObject.stringData); - } - - @Test - public void verifyGetAndPutArrayValue() { - SomeData testObject = new SomeData(); - Chunk chunk = new ChunkAdapter(testObject); - testObject.setArrayData(new long[] { 0xADD } ); - - assertArrayEquals(new long[] { 0xADD }, chunk.get(arrayData)); - - chunk.put(arrayData, new long[] { 0xC0FFEE }); - - assertArrayEquals(new long[] { 0xC0FFEE }, chunk.get(arrayData)); - assertArrayEquals(new long[] { 0xC0FFEE }, testObject.arrayData); - } - - @Test - public void verifyGetAndPutListValue() { - SomeData testObject = new SomeData(); - Chunk chunk = new ChunkAdapter(testObject); - List<String> newList = new ArrayList<>(); - testObject.setListData(newList); - - assertEquals(newList, chunk.get(listData)); - - chunk.put(listData, Collections.<String>emptyList()); - - assertSame(Collections.<String>emptyList(), chunk.get(listData)); - assertSame(Collections.<String>emptyList(), testObject.listData); - } - - @Test (expected=IllegalArgumentException.class) - public void verifyNonEntityIsNotAcceptable() { - // missing @Entity annotation - class NonEntity { - public void setInteger(int integer) { /* no op */ } - public int getInteger() { return 42; } - } - - NonEntity toAdapt = new NonEntity(); - new ChunkAdapter(toAdapt); - } - - @Test (expected=IllegalArgumentException.class) - public void verifyMissingPersistAnnotationOnOneMethodThrowsException() { - @Entity - class DataWithMissingAnnotationOnOneMethod { - @Persist public void setInteger(int integer) { /* no op */ } - public int getInteger() { return 42; } - } - - DataWithMissingAnnotationOnOneMethod toAdapt = new DataWithMissingAnnotationOnOneMethod(); - new ChunkAdapter(toAdapt); - } - - @Test - public void verifyCustomEntityNameIsCategoryName() { - final String ENTITY_NAME = "custom-data-name"; - - @Entity (name=ENTITY_NAME) - class DataWithCustomName { - public void setData(String data) { /* no-op */ } - public String getData() { return "ignore this value" ; } - } - - Chunk chunk = new ChunkAdapter(new DataWithCustomName()); - - assertEquals(ENTITY_NAME, chunk.getCategory().getName()); - } - - @Test - public void verifyCustomAttributeNameOnGetIsKeyName() { - final String ATTRIBUTE_NAME = "custom-attribute"; - Key<?> expectedKey = new Key<>(ATTRIBUTE_NAME, false); - - @Entity - class DataWithCustomAttributeNameOnGet { - @Persist (name=ATTRIBUTE_NAME) - public String getCustomAttribute() { return "ignore this value" ; } - @Persist - public void setCustomAttribute(String attribute) { /* no op */ } - } - - Chunk chunk = new ChunkAdapter(new DataWithCustomAttributeNameOnGet()); - - assertTrue(chunk.getKeys().contains(expectedKey)); - - assertTrue(chunk.getCategory().getKeys().contains(expectedKey)); - assertNotNull(chunk.getCategory().getKey(ATTRIBUTE_NAME)); - } - - @Test - public void verifyCustomAttributeNameOnSetIsKeyName() { - final String ATTRIBUTE_NAME = "custom-attribute"; - Key<?> expectedKey = new Key<>(ATTRIBUTE_NAME, false); - - @Entity - class DataWithCustomAttributeNameOnSet { - @Persist - public String getCustomAttribute() { return "ignore this value" ; } - @Persist (name=ATTRIBUTE_NAME) - public void setCustomAttribute(String attribute) { /* no op */ } - } - - Chunk chunk = new ChunkAdapter(new DataWithCustomAttributeNameOnSet()); - - assertTrue(chunk.getKeys().contains(expectedKey)); - - assertTrue(chunk.getCategory().getKeys().contains(expectedKey)); - assertNotNull(chunk.getCategory().getKey(ATTRIBUTE_NAME)); - } - - @Test (expected=IllegalArgumentException.class) - public void verifyExceptionOnCustomAttributeNameMismatch() { - @Entity - class DataWithCustomAttributeNameMismatch { - @Persist (name="one-name") - public String getCustomAttribute() { return "ignore this value" ; } - @Persist (name="different-name") - public void setCustomAttribute(String attribute) { /* no op */ } - } - - new ChunkAdapter(new DataWithCustomAttributeNameMismatch()); - } - - @Test - public void verifyGetAndPutNestedValue() { - NestedData nested = new NestedData(); - nested.setData("stringData"); - SomeData testObject = new SomeData(); - testObject.setNestedData(nested); - Chunk chunk = new ChunkAdapter(testObject); - - assertEquals("stringData", chunk.get(nestedData)); - - chunk.put(nestedData, "some-new-data"); - - assertEquals("some-new-data", chunk.get(nestedData)); - assertEquals("some-new-data", testObject.getNestedData().getData()); - } -}
--- a/common/core/src/test/java/com/redhat/thermostat/common/storage/ChunkConverterTest.java Fri Oct 26 13:12:46 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,370 +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.storage; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; - -import java.util.Arrays; -import java.util.List; - -import org.junit.Test; - -import com.mongodb.BasicDBObject; -import com.mongodb.DBObject; - -public class ChunkConverterTest { - - 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); - private static final Key<String> key4 = new Key<>("key4", false); - private static final Key<String> key5 = new Key<>("key5", false); - - private static final Key<String> key1_key1 = new Key<>("key1.key1", false); - private static final Key<String> key1_key2 = new Key<>("key1.key2", false); - private static final Key<String> key1_key2_key1 = new Key<>("key1.key2.key1", false); - private static final Key<String> key1_key2_key2 = new Key<>("key1.key2.key2", false); - private static final Key<String> key1_key2_key3 = new Key<>("key1.key2.key3", false); - private static final Key<String> key2_key1 = new Key<>("key2.key1", false); - private static final Key<String> key2_key2 = new Key<>("key2.key2", false); - private static final Key<String> key2_key3 = new Key<>("key2.key3", false); - - private static final Key<List<Integer>> listKey = new Key<>("list", false); - - private static final String mongoId = "_id"; - private static final Key<String> invalidMongoIdKey = new Key<>(mongoId, false); - - private static final Category testCategory = new Category("ChunkConverterTest", key1, key2, key3, key4, key5, - key1_key1, key1_key2, key2_key1, key2_key2, key2_key3, - key1_key2_key1, key1_key2_key2, key1_key2_key3); - private static final Category smallerCategory = new Category("SmallerTest", key1, key2); - - private static final Category listCategory = new Category("something-with-lists", listKey); - - @Test - public void verifyBasicChunkToDBObject() { - Chunk chunk = new Chunk(testCategory, false); - chunk.put(key1, "test1"); - - ChunkConverter converter = new ChunkConverter(); - DBObject dbObject = converter.chunkToDBObject(chunk); - - assertEquals(1, dbObject.keySet().size()); - assertTrue(dbObject.keySet().contains("key1")); - assertEquals("test1", dbObject.get("key1")); - } - - @Test - public void verifyChunkToDBObjectInOrder() { - Chunk chunk = new Chunk(testCategory, false); - chunk.put(key5, "test1"); - chunk.put(key4, "test2"); - chunk.put(key3, "test3"); - chunk.put(key2, "test4"); - chunk.put(key1, "test5"); - - ChunkConverter converter = new ChunkConverter(); - DBObject dbObject = converter.chunkToDBObject(chunk); - - assertEquals(5, dbObject.keySet().size()); - assertArrayEquals(new String[]{"key5", "key4", "key3", "key2", "key1"}, dbObject.keySet().toArray()); - } - - @Test - public void verifyChunkToDBObjectWithLists() { - Chunk chunk = new Chunk(listCategory, false); - chunk.put(listKey, Arrays.asList(1, 2, 3, 4)); - - ChunkConverter converter = new ChunkConverter(); - DBObject dbObj = converter.chunkToDBObject(chunk); - - assertEquals(Arrays.asList(1,2,3,4), dbObj.get("list")); - - } - - @Test - public void verifyBasicDBObjectToChunk() { - BasicDBObject dbObject = new BasicDBObject(); - dbObject.put("key1", "test1"); - - ChunkConverter converter = new ChunkConverter(); - Chunk chunk = converter.dbObjectToChunk(dbObject, testCategory); - - assertSame(testCategory, chunk.getCategory()); - assertEquals(1, chunk.getKeys().size()); - assertTrue(chunk.getKeys().contains(key1)); - assertEquals("test1", chunk.get(key1)); - - } - - @Test - public void verifyDBObjectToChunkInOrder() { - BasicDBObject dbObject = new BasicDBObject(); - dbObject.put("key5", "test1"); - dbObject.put("key4", "test2"); - dbObject.put("key3", "test3"); - dbObject.put("key2", "test4"); - dbObject.put("key1", "test5"); - - ChunkConverter converter = new ChunkConverter(); - Chunk chunk = converter.dbObjectToChunk(dbObject, testCategory); - - assertSame(testCategory, chunk.getCategory()); - assertEquals(5, chunk.getKeys().size()); - assertArrayEquals(new Key<?>[]{ key5, key4, key3, key2, key1 }, chunk.getKeys().toArray()); - assertEquals("test5", chunk.get(key1)); - assertEquals("test4", chunk.get(key2)); - assertEquals("test3", chunk.get(key3)); - assertEquals("test2", chunk.get(key4)); - assertEquals("test1", chunk.get(key5)); - - } - - @Test - public void verifyDBObjectToChunkWithLists() { - BasicDBObject dbObj = new BasicDBObject(); - dbObj.put("list", Arrays.asList(1, 2, 3, 4)); - - ChunkConverter converter = new ChunkConverter(); - Chunk chunk = converter.dbObjectToChunk(dbObj, listCategory); - - List<Integer> data = chunk.get(listKey); - assertEquals(Arrays.asList(1, 2, 3, 4), data); - } - - @Test - public void verifySimpleNestedChunkToObject() { - Chunk chunk = new Chunk(testCategory, false); - chunk.put(key1_key1, "test1"); - - ChunkConverter converter = new ChunkConverter(); - DBObject dbObject = converter.chunkToDBObject(chunk); - - assertEquals(1, dbObject.keySet().size()); - assertTrue(dbObject.keySet().contains("key1")); - DBObject nested = (DBObject) dbObject.get("key1"); - assertEquals(1, nested.keySet().size()); - assertTrue(nested.keySet().contains("key1")); - assertEquals("test1", nested.get("key1")); - } - - @Test - public void verifyComplexNestedChunkToObject() { - Chunk chunk = new Chunk(testCategory, false); - chunk.put(key1_key1, "test1"); - chunk.put(key1_key2, "test2"); - chunk.put(key2_key1, "test3"); - chunk.put(key2_key2, "test4"); - chunk.put(key2_key3, "test5"); - chunk.put(key3, "test6"); - - ChunkConverter converter = new ChunkConverter(); - DBObject dbObject = converter.chunkToDBObject(chunk); - - assertEquals(3, dbObject.keySet().size()); - assertTrue(dbObject.keySet().contains("key1")); - assertTrue(dbObject.keySet().contains("key2")); - assertTrue(dbObject.keySet().contains("key3")); - assertEquals("test6", dbObject.get("key3")); - - DBObject nested1 = (DBObject) dbObject.get("key1"); - assertEquals(2, nested1.keySet().size()); - assertTrue(nested1.keySet().contains("key1")); - assertTrue(nested1.keySet().contains("key2")); - assertEquals("test1", nested1.get("key1")); - assertEquals("test2", nested1.get("key2")); - - DBObject nested2 = (DBObject) dbObject.get("key2"); - assertEquals(3, nested2.keySet().size()); - assertTrue(nested2.keySet().contains("key1")); - assertTrue(nested2.keySet().contains("key2")); - assertTrue(nested2.keySet().contains("key3")); - assertEquals("test3", nested2.get("key1")); - assertEquals("test4", nested2.get("key2")); - assertEquals("test5", nested2.get("key3")); - } - - @Test - public void verifyComplex3LevelChunkToObject() { - Chunk chunk = new Chunk(testCategory, false); - chunk.put(key1_key1, "test1"); - chunk.put(key1_key2_key1, "test3"); - chunk.put(key1_key2_key2, "test4"); - chunk.put(key1_key2_key3, "test5"); - chunk.put(key3, "test6"); - - ChunkConverter converter = new ChunkConverter(); - DBObject dbObject = converter.chunkToDBObject(chunk); - - assertEquals(2, dbObject.keySet().size()); - assertTrue(dbObject.keySet().contains("key1")); - assertTrue(dbObject.keySet().contains("key3")); - assertEquals("test6", dbObject.get("key3")); - - DBObject nested1 = (DBObject) dbObject.get("key1"); - assertEquals(2, nested1.keySet().size()); - assertTrue(nested1.keySet().contains("key1")); - assertTrue(nested1.keySet().contains("key2")); - assertEquals("test1", nested1.get("key1")); - - DBObject nested2 = (DBObject) nested1.get("key2"); - assertEquals(3, nested2.keySet().size()); - assertTrue(nested2.keySet().contains("key1")); - assertTrue(nested2.keySet().contains("key2")); - assertTrue(nested2.keySet().contains("key3")); - assertEquals("test3", nested2.get("key1")); - assertEquals("test4", nested2.get("key2")); - assertEquals("test5", nested2.get("key3")); - } - - @Test - public void verifySimpleNestedObjectToChunk() { - BasicDBObject nested = new BasicDBObject(); - nested.put("key1", "test1"); - BasicDBObject dbObject = new BasicDBObject(); - dbObject.put("key1", nested); - - ChunkConverter converter = new ChunkConverter(); - Chunk chunk = converter.dbObjectToChunk(dbObject, testCategory); - - assertSame(testCategory, chunk.getCategory()); - assertEquals(1, chunk.getKeys().size()); - assertTrue(chunk.getKeys().contains(key1_key1)); - assertEquals("test1", chunk.get(key1_key1)); - } - - @Test - public void verifyComplexNestedObjectToChunk() { - BasicDBObject nested1 = new BasicDBObject(); - nested1.put("key1", "test1"); - nested1.put("key2", "test2"); - - BasicDBObject nested2 = new BasicDBObject(); - nested2.put("key1", "test3"); - nested2.put("key2", "test4"); - nested2.put("key3", "test5"); - - BasicDBObject dbObject = new BasicDBObject(); - dbObject.put("key1", nested1); - dbObject.put("key2", nested2); - dbObject.put("key3", "test6"); - - ChunkConverter converter = new ChunkConverter(); - Chunk chunk = converter.dbObjectToChunk(dbObject, testCategory); - - assertSame(testCategory, chunk.getCategory()); - - assertEquals(6, chunk.getKeys().size()); - assertTrue(chunk.getKeys().contains(key1_key1)); - assertTrue(chunk.getKeys().contains(key1_key2)); - assertTrue(chunk.getKeys().contains(key2_key1)); - assertTrue(chunk.getKeys().contains(key2_key2)); - assertTrue(chunk.getKeys().contains(key2_key3)); - assertTrue(chunk.getKeys().contains(key3)); - assertEquals("test1", chunk.get(key1_key1)); - assertEquals("test2", chunk.get(key1_key2)); - assertEquals("test3", chunk.get(key2_key1)); - assertEquals("test4", chunk.get(key2_key2)); - assertEquals("test5", chunk.get(key2_key3)); - assertEquals("test6", chunk.get(key3)); - } - - @Test - public void verifyComplex3LevelObjectToChunk() { - - BasicDBObject nested2 = new BasicDBObject(); - nested2.put("key1", "test3"); - nested2.put("key2", "test4"); - nested2.put("key3", "test5"); - - BasicDBObject nested1 = new BasicDBObject(); - nested1.put("key1", "test1"); - nested1.put("key2", nested2); - - BasicDBObject dbObject = new BasicDBObject(); - dbObject.put("key1", nested1); - dbObject.put("key3", "test6"); - - ChunkConverter converter = new ChunkConverter(); - Chunk chunk = converter.dbObjectToChunk(dbObject, testCategory); - - assertSame(testCategory, chunk.getCategory()); - - assertEquals(5, chunk.getKeys().size()); - assertTrue(chunk.getKeys().contains(key1_key1)); - assertTrue(chunk.getKeys().contains(key1_key2_key1)); - assertTrue(chunk.getKeys().contains(key1_key2_key2)); - assertTrue(chunk.getKeys().contains(key1_key2_key3)); - assertTrue(chunk.getKeys().contains(key3)); - - assertEquals("test1", chunk.get(key1_key1)); - assertEquals("test3", chunk.get(key1_key2_key1)); - assertEquals("test4", chunk.get(key1_key2_key2)); - assertEquals("test5", chunk.get(key1_key2_key3)); - assertEquals("test6", chunk.get(key3)); - } - - @Test - public void verifyDBObjectToChunkIgnoresMongoID() { - DBObject obj = new BasicDBObject(mongoId, "mongo_private_info"); - ChunkConverter converter = new ChunkConverter(); - Chunk chunk = converter.dbObjectToChunk(obj, new Category("invalidCategory", invalidMongoIdKey)); - - assertEquals(1, chunk.getKeys().size()); - assertEquals("mongo_private_info", chunk.get(Key.ID)); - } - - @Test - public void verifyDBObjectToChunkAvoidsNonExistentKeys() { - DBObject obj = new BasicDBObject("key1", "data1"); - obj.put("key2", "data2"); - obj.put("key3", "data3"); // This one is not a part of smallerCategory - ChunkConverter converter = new ChunkConverter(); - Chunk chunk = converter.dbObjectToChunk(obj, smallerCategory); - - assertEquals(2, chunk.getKeys().size()); - assertFalse(chunk.getKeys().contains(key3)); - assertTrue(chunk.getKeys().contains(key1)); - assertTrue(chunk.getKeys().contains(key2)); - assertEquals("data1", chunk.get(key1)); - assertEquals("data2", chunk.get(key2)); - } -}
--- a/common/core/src/test/java/com/redhat/thermostat/common/storage/ChunkTest.java Fri Oct 26 13:12:46 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,236 +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.storage; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import org.junit.Test; - -public class ChunkTest { - - 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); - private static final Key<String> key4 = new Key<>("key4", false); - private static final Key<String> key5 = new Key<>("key5", false); - private static final Key<Integer> key6 = new Key<>("key6", false); - private static final Key<Object> key7 = new Key<>("key7", false); - - private static final String value1 = "test1"; - private static final String value2 = "test2"; - private static final String value3 = "test3"; - private static final String value4 = "test4"; - private static final String value5 = "test5"; - private static final int value6 = 12345; - private static final Object value7 = "test7"; - - private static final Category testCategory = new Category("ChunkTest", key1, key2, key3, key4, key5); - private static final Category testCategory2 = new Category("ChunkTest2", key1, key2, key3, key4, key5); - - @Test - public void verifyGetCategoryNotNull() { - Chunk chunk = new Chunk(testCategory, false); - Category cat = chunk.getCategory(); - assertNotNull(cat); - } - - @Test - public void verifyGetCategoryReturnsCorrectCategory() { - Chunk chunk = new Chunk(testCategory, false); - Category cat = chunk.getCategory(); - assertEquals(cat, testCategory); - } - - @Test - public void verifyGetReplaceReturnsCorrectValue() { - Chunk chunk = new Chunk(testCategory, false); - boolean replace = chunk.getReplace(); - assertFalse(replace); - chunk = new Chunk(testCategory, true); - replace = chunk.getReplace(); - assertTrue(replace); - } - - @Test - public void verifyPutActuallyPuts() { - Chunk chunk = new Chunk(testCategory, false); - chunk.put(key1, value1); - int pieces = chunk.getKeys().size(); - assertEquals(pieces, 1); - } - - @Test - public void verifyPutPutsCorrectly() { - Chunk chunk = new Chunk(testCategory, false); - chunk.put(key1, value1); - String value = chunk.get(key1); - assertEquals(value, value1); - } - - @Test - public void verifyPutAcceptsVariousTypes() { - Chunk chunk = new Chunk(testCategory, false); - chunk.put(key1, value1); - chunk.put(key5, value5); - chunk.put(key6, value6); - chunk.put(key7, value7); - int pieces = chunk.getKeys().size(); - assertEquals(pieces, 4); - } - - @Test - public void verifyEntriesAreKeptInOrder() { - Chunk chunk = new Chunk(testCategory, false); - chunk.put(key5, value5); - chunk.put(key4, value4); - chunk.put(key3, value3); - chunk.put(key2, value2); - chunk.put(key1, value1); - - assertArrayEquals(new Key<?>[]{key5, key4, key3, key2, key1}, chunk.getKeys().toArray()); - } - - @Test - public void verifyGetNotNull() { - Chunk chunk = new Chunk(testCategory, false); - chunk.put(key1, value1); - String value = chunk.get(key1); - assertNotNull(value); - } - - @Test - public void verifyGetNullWhenExpected() { - Chunk chunk = new Chunk(testCategory, false); - chunk.put(key1, value1); - String value = chunk.get(key2); - assertNull(value); - } - - - @Test - public void testEqualsBasicEquals() { - Chunk chunk1 = new Chunk(testCategory, false); - Chunk chunk2 = new Chunk(testCategory, false); - assertTrue(chunk1.equals(chunk2)); - } - - @Test - public void testEqualsDifferentCategory() { - Chunk chunk1 = new Chunk(testCategory, false); - Chunk chunk2 = new Chunk(testCategory2, false); - assertFalse(chunk1.equals(chunk2)); - } - - @Test - public void testEqualsDifferentReplace() { - // TODO: Do we want to differentiate chunks by that flag? I think not. Maybe it doesn't even belong in chunk. - Chunk chunk1 = new Chunk(testCategory, false); - Chunk chunk2 = new Chunk(testCategory, true); - assertTrue(chunk1.equals(chunk2)); - } - - @Test - public void testEqualsDifferentType() { - Chunk chunk1 = new Chunk(testCategory, false); - assertFalse(chunk1.equals("fluff")); - } - - @Test - public void testEqualsNull() { - Chunk chunk1 = new Chunk(testCategory, false); - assertFalse(chunk1.equals(null)); - } - - @Test - public void testEqualsDifferentNumberOfValues() { - Chunk chunk1 = new Chunk(testCategory, false); - chunk1.put(key1, "value1"); - chunk1.put(key2, "value2"); - Chunk chunk2 = new Chunk(testCategory, true); - chunk2.put(key1, "value1"); - assertFalse(chunk1.equals(chunk2)); - } - - @Test - public void testEqualsDifferentKeys() { - Chunk chunk1 = new Chunk(testCategory, false); - chunk1.put(key1, "value1"); - chunk1.put(key2, "value2"); - Chunk chunk2 = new Chunk(testCategory, true); - chunk2.put(key1, "value1"); - chunk2.put(key3, "value2"); - assertFalse(chunk1.equals(chunk2)); - } - - @Test - public void testEqualsDifferentValues() { - Chunk chunk1 = new Chunk(testCategory, false); - chunk1.put(key1, "value1"); - chunk1.put(key2, "value2.1"); - Chunk chunk2 = new Chunk(testCategory, true); - chunk2.put(key1, "value1"); - chunk2.put(key2, "value2.2"); - assertFalse(chunk1.equals(chunk2)); - } - - @Test - public void testEqualsSameValues() { - Chunk chunk1 = new Chunk(testCategory, false); - chunk1.put(key1, "value1"); - chunk1.put(key2, "value2"); - Chunk chunk2 = new Chunk(testCategory, true); - chunk2.put(key1, "value1"); - chunk2.put(key2, "value2"); - assertTrue(chunk1.equals(chunk2)); - } - - @Test - public void testEqualsNullValues() { - Chunk chunk1 = new Chunk(testCategory, false); - chunk1.put(key1, "value1"); - chunk1.put(key2, null); - Chunk chunk2 = new Chunk(testCategory, true); - chunk2.put(key1, "value1"); - chunk2.put(key2, null); - assertTrue(chunk1.equals(chunk2)); - } -}
--- a/common/core/src/test/java/com/redhat/thermostat/common/storage/MongoCursorTest.java Fri Oct 26 13:12:46 2012 +0200 +++ b/common/core/src/test/java/com/redhat/thermostat/common/storage/MongoCursorTest.java Fri Oct 26 13:13:42 2012 +0200 @@ -121,7 +121,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<TestClass>(dbCursor, testCategory, TestClass.class, null); + cursor = new MongoCursor<TestClass>(dbCursor, TestClass.class); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/core/src/test/java/com/redhat/thermostat/common/storage/MongoPojoConverterTest.java Fri Oct 26 13:13:42 2012 +0200 @@ -0,0 +1,323 @@ +/* + * 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 static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +import com.mongodb.BasicDBObject; +import com.mongodb.DBObject; +import com.redhat.thermostat.common.model.Pojo; + +public class MongoPojoConverterTest { + + @Entity + public static class SimplePojo implements Pojo { + + private String test; + private String ignored; + + + @Persist + public String getTest() { + return test; + } + + @Persist + public void setTest(String test) { + this.test = test; + } + + public String getIgnored() { + return ignored; + } + + public void setIgnored(String ignored) { + this.ignored = ignored; + } + + } + + @Entity + public static class NestedPojo extends SimplePojo { + + private SimplePojo nested; + + @Persist + public SimplePojo getNested() { + return nested; + } + + @Persist + public void setNested(SimplePojo nested) { + this.nested = nested; + } + } + + @Entity + public static class IndexedPojo extends SimplePojo { + + private SimplePojo[] indexed; + + @Persist + public SimplePojo[] getIndexed() { + return indexed; + } + + @Persist + public void setIndexed(SimplePojo[] indexed) { + this.indexed = indexed; + } + } + + @Entity + public static class PrimitiveIndexedPojo extends SimplePojo { + + private int[] indexed; + + @Persist + public int[] getIndexed() { + return indexed; + } + + @Persist + public void setIndexed(int[] indexed) { + this.indexed = indexed; + } + } + + public static class BrokenPojo1 extends SimplePojo { + private int broken; + + @Persist + public void setBroken(int broken) { + this.broken = broken; + } + } + + public static class BrokenPojo2 extends SimplePojo { + private int broken; + + @Persist + public void setBroken(int broken) { + this.broken = broken; + } + + public int getBroken() { + return broken; + } + } + + @Test + public void testConvertSimplePojoToMongo() { + MongoPojoConverter conv = new MongoPojoConverter(); + SimplePojo obj = new SimplePojo(); + obj.setTest("fluff"); + DBObject dbObject = conv.convertPojoToMongo(obj); + assertEquals(1, dbObject.keySet().size()); + assertEquals("fluff", dbObject.get("test")); + } + + @Test + public void testConvertSimplePojoFromMongo() { + MongoPojoConverter conv = new MongoPojoConverter(); + DBObject dbObj = new BasicDBObject(); + dbObj.put("test", "fluff"); + SimplePojo obj = conv.convertMongoToPojo(dbObj, SimplePojo.class); + assertEquals("fluff", obj.getTest()); + assertNull(obj.getIgnored()); + } + + @Test(expected=StorageException.class) + public void testConvertSimplePojoFromMongoExtraProperty() { + MongoPojoConverter conv = new MongoPojoConverter(); + DBObject dbObj = new BasicDBObject(); + dbObj.put("test", "fluff"); + dbObj.put("foo", "bar"); + conv.convertMongoToPojo(dbObj, SimplePojo.class); + } + + @Test(expected=StorageException.class) + public void testConvertSimplePojoFromMongoBrokenPojo1() { + MongoPojoConverter conv = new MongoPojoConverter(); + DBObject dbObj = new BasicDBObject(); + dbObj.put("broken", "foo"); + conv.convertMongoToPojo(dbObj, BrokenPojo1.class); + } + + + @Test(expected=StorageException.class) + public void testConvertSimplePojoFromMongoBrokenPojo2() { + MongoPojoConverter conv = new MongoPojoConverter(); + DBObject dbObj = new BasicDBObject(); + dbObj.put("broken", "foo"); + conv.convertMongoToPojo(dbObj, BrokenPojo2.class); + } + + @Test + public void testConvertNestedPojoToMongo() { + MongoPojoConverter conv = new MongoPojoConverter(); + NestedPojo obj = new NestedPojo(); + obj.setTest("foo"); + SimplePojo nested = new SimplePojo(); + nested.setTest("bar"); + obj.setNested(nested); + DBObject dbObject = conv.convertPojoToMongo(obj); + assertEquals(2, dbObject.keySet().size()); + assertEquals("foo", dbObject.get("test")); + DBObject nestedDbObj = (DBObject) dbObject.get("nested"); + assertEquals(1, nestedDbObj.keySet().size()); + assertEquals("bar", nestedDbObj.get("test")); + } + + @Test + public void testConvertNestedPojoFromMongo() { + MongoPojoConverter conv = new MongoPojoConverter(); + DBObject nested = new BasicDBObject(); + nested.put("test", "bar"); + DBObject dbObj = new BasicDBObject(); + dbObj.put("test", "foo"); + dbObj.put("nested", nested); + NestedPojo obj = conv.convertMongoToPojo(dbObj, NestedPojo.class); + assertEquals("foo", obj.getTest()); + assertNull(obj.getIgnored()); + assertNotNull(obj.getNested()); + assertEquals("bar", obj.getNested().getTest()); + assertEquals(null, obj.getNested().getIgnored()); + } + + @Test + public void testConvertIndexedPojoToMongo() { + MongoPojoConverter conv = new MongoPojoConverter(); + IndexedPojo obj = new IndexedPojo(); + obj.setTest("test"); + SimplePojo obj1 = new SimplePojo(); + obj1.setTest("test1"); + SimplePojo obj2 = new SimplePojo(); + obj2.setTest("test2"); + SimplePojo obj3 = new SimplePojo(); + obj3.setTest("test3"); + obj.setIndexed(new SimplePojo[] { obj1, obj2, obj3 }); + + DBObject dbObject = conv.convertPojoToMongo(obj); + assertEquals(2, dbObject.keySet().size()); + assertEquals("test", dbObject.get("test")); + List<?> indexedDbObj = (List<?>) dbObject.get("indexed"); + assertEquals(3, indexedDbObj.size()); + + DBObject dbObj1 = (DBObject) indexedDbObj.get(0); + assertEquals(1, dbObj1.keySet().size()); + assertEquals("test1", dbObj1.get("test")); + + DBObject dbObj2 = (DBObject) indexedDbObj.get(1); + assertEquals(1, dbObj2.keySet().size()); + assertEquals("test2", dbObj2.get("test")); + + DBObject dbObj3 = (DBObject) indexedDbObj.get(2); + assertEquals(1, dbObj3.keySet().size()); + assertEquals("test3", dbObj3.get("test")); + } + + @Test + public void testConvertPrimitiveIndexedPojoToMongo() { + MongoPojoConverter conv = new MongoPojoConverter(); + PrimitiveIndexedPojo obj = new PrimitiveIndexedPojo(); + obj.setTest("test"); + obj.setIndexed(new int[] { 1, 2, 3 }); + + DBObject dbObject = conv.convertPojoToMongo(obj); + assertEquals(2, dbObject.keySet().size()); + assertEquals("test", dbObject.get("test")); + List<?> indexedDbObj = (List<?>) dbObject.get("indexed"); + assertEquals(3, indexedDbObj.size()); + + assertEquals(1, indexedDbObj.get(0)); + assertEquals(2, indexedDbObj.get(1)); + assertEquals(3, indexedDbObj.get(2)); + + } + + @Test + public void testConvertIndexedPojoFromMongo() { + MongoPojoConverter conv = new MongoPojoConverter(); + DBObject indexed = new BasicDBObject(); + indexed.put("test", "test"); + DBObject dbObj1 = new BasicDBObject(); + dbObj1.put("test", "test1"); + DBObject dbObj2 = new BasicDBObject(); + dbObj2.put("test", "test2"); + DBObject dbObj3 = new BasicDBObject(); + dbObj3.put("test", "test3"); + indexed.put("indexed", Arrays.asList(dbObj1, dbObj2, dbObj3)); + + IndexedPojo obj = conv.convertMongoToPojo(indexed, IndexedPojo.class); + assertEquals("test", obj.getTest()); + assertNull(obj.getIgnored()); + assertNotNull(obj.getIndexed()); + SimplePojo[] indexedObj = obj.getIndexed(); + assertEquals("test1", indexedObj[0].getTest()); + assertNull(indexedObj[0].getIgnored()); + assertEquals("test2", indexedObj[1].getTest()); + assertNull(indexedObj[1].getIgnored()); + assertEquals("test3", indexedObj[2].getTest()); + assertNull(indexedObj[2].getIgnored()); + } + + @Test + public void testConvertPrimitiveIndexedPojoFromMongo() { + MongoPojoConverter conv = new MongoPojoConverter(); + DBObject indexed = new BasicDBObject(); + indexed.put("test", "test"); + indexed.put("indexed", Arrays.asList(1, 2, 3)); + + PrimitiveIndexedPojo obj = conv.convertMongoToPojo(indexed, PrimitiveIndexedPojo.class); + assertEquals("test", obj.getTest()); + assertNull(obj.getIgnored()); + assertNotNull(obj.getIndexed()); + int[] indexedObj = obj.getIndexed(); + assertEquals(1, indexedObj[0]); + assertEquals(2, indexedObj[1]); + assertEquals(3, indexedObj[2]); + } +}
--- a/common/core/src/test/java/com/redhat/thermostat/common/storage/MongoStorageTest.java Fri Oct 26 13:12:46 2012 +0200 +++ b/common/core/src/test/java/com/redhat/thermostat/common/storage/MongoStorageTest.java Fri Oct 26 13:13:42 2012 +0200 @@ -36,7 +36,6 @@ 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.assertNotNull; @@ -131,8 +130,8 @@ } } - 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> key1 = new Key<>("key1", true); + private static final Key<String> key2 = new Key<>("key2", true); private static final Key<String> key3 = new Key<>("key3", false); private static final Key<String> key4 = new Key<>("key4", false); private static final Key<String> key5 = new Key<>("key5", false); @@ -140,7 +139,6 @@ private static final Category emptyTestCategory = new Category("MongoEmptyCategory"); private StartupConfiguration conf; - private Chunk multiKeyQuery; private Mongo m; private DB db; private DBCollection testCollection, emptyTestCollection, mockedCollection; @@ -171,13 +169,6 @@ value2.put("key3", "test3"); value2.put("key4", "test4"); - multiKeyQuery = new Chunk(testCategory, false); - multiKeyQuery.put(key5, "test1"); - multiKeyQuery.put(key4, "test2"); - multiKeyQuery.put(key3, "test3"); - multiKeyQuery.put(key2, "test4"); - multiKeyQuery.put(key1, "test5"); - cursor = mock(DBCursor.class); when(cursor.hasNext()).thenReturn(true).thenReturn(true).thenReturn(false); when(cursor.next()).thenReturn(value1).thenReturn(value2).thenReturn(null); @@ -200,7 +191,6 @@ db = null; testCollection = null; emptyTestCollection = null; - multiKeyQuery = null; cursor = null; } @@ -208,7 +198,7 @@ public void verifyFindOnlyAcceptsMongoQuery() { MongoStorage storage = makeStorage(); Query query = mock(Query.class); - storage.find(query); + storage.findPojo(query, TestClass.class); } @Test (expected=IllegalArgumentException.class) @@ -232,7 +222,7 @@ PowerMockito.whenNew(Mongo.class).withParameterTypes(MongoURI.class).withArguments(any(MongoURI.class)).thenReturn(m); MongoStorage storage = makeStorage(); Query query = storage.createQuery().from(testCategory).where(key1, Criteria.EQUALS, "test1"); - Chunk result = storage.find(query); + TestClass result = storage.findPojo(query, TestClass.class); assertNotNull(result); } @@ -250,7 +240,7 @@ PowerMockito.whenNew(Mongo.class).withParameterTypes(MongoURI.class).withArguments(any(MongoURI.class)).thenReturn(m); MongoStorage storage = makeStorage(); Query query = storage.createQuery().from(testCategory); - storage.find(query); + storage.findPojo(query, TestClass.class); verify(testCollection).findOne(any(DBObject.class)); } @@ -284,7 +274,7 @@ ArgumentCaptor<DBObject> findArg = ArgumentCaptor.forClass(DBObject.class); - storage.find(query); + storage.findPojo(query, TestClass.class); verify(testCollection).findOne(findArg.capture()); assertSame(generatedQuery, findArg.getValue()); @@ -298,12 +288,11 @@ // Because we mock the DBCollection, the contents of this query don't actually determine the result. MongoQuery query = new MongoQuery().from(testCategory); - Chunk result = storage.find(query); + TestClass result = storage.findPojo(query, TestClass.class); assertNotNull(result); - assertArrayEquals(new Key<?>[]{key1, key2}, result.getKeys().toArray()); - assertEquals("test1", result.get(key1)); - assertEquals("test2", result.get(key2)); + assertEquals("test1", result.getKey1()); + assertEquals("test2", result.getKey2()); } @Test @@ -415,9 +404,9 @@ public void verifyPutChunkUsesCorrectChunkAgent() throws Exception { PowerMockito.whenNew(Mongo.class).withParameterTypes(MongoURI.class).withArguments(any(MongoURI.class)).thenReturn(m); MongoStorage storage = makeStorage(); - Chunk chunk1 = new Chunk(testCategory, false); - chunk1.put(Key.AGENT_ID, "123"); - storage.putChunk(chunk1); + TestClass pojo = new TestClass(); + pojo.setAgentId("123"); + storage.putPojo(testCategory, false, pojo); ArgumentCaptor<DBObject> dbobj = ArgumentCaptor.forClass(DBObject.class); verify(testCollection).insert(dbobj.capture()); DBObject val = dbobj.getValue(); @@ -429,9 +418,9 @@ PowerMockito.whenNew(Mongo.class).withParameterTypes(MongoURI.class).withArguments(any(MongoURI.class)).thenReturn(m); MongoStorage storage = makeStorage(); storage.setAgentId(new UUID(1, 2)); - Chunk chunk1 = new Chunk(testCategory, false); - chunk1.put(Key.AGENT_ID, "123"); - storage.putChunk(chunk1); + TestClass pojo = new TestClass(); + pojo.setAgentId("123"); + storage.putPojo(testCategory, false, pojo); ArgumentCaptor<DBObject> dbobj = ArgumentCaptor.forClass(DBObject.class); verify(testCollection).insert(dbobj.capture()); DBObject val = dbobj.getValue(); @@ -493,4 +482,35 @@ assertEquals("test3", values.get("key3")); } + @Test + public void verifyInsertReplaceCallsUpdate() { + TestClass pojo = new TestClass(); + pojo.setAgentId("123"); + pojo.setKey1("test1"); + pojo.setKey2("test2"); + pojo.setKey3("test3"); + pojo.setKey4("test4"); + pojo.setKey5("test5"); + + MongoStorage storage = makeStorage(); + storage.putPojo(testCategory, true, pojo); + + ArgumentCaptor<DBObject> queryCaptor = ArgumentCaptor.forClass(DBObject.class); + ArgumentCaptor<DBObject> valueCaptor = ArgumentCaptor.forClass(DBObject.class); + verify(testCollection).update(queryCaptor.capture(), valueCaptor.capture()); + + DBObject query = queryCaptor.getValue(); + assertEquals(2, query.keySet().size()); + assertEquals("test1", query.get("key1")); + assertEquals("test2", query.get("key2")); + + DBObject value = valueCaptor.getValue(); + assertEquals(6, value.keySet().size()); + assertEquals("test1", value.get("key1")); + assertEquals("test2", value.get("key2")); + assertEquals("test3", value.get("key3")); + assertEquals("test4", value.get("key4")); + assertEquals("test5", value.get("key5")); + assertEquals("123", value.get("agentId")); + } }
--- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/CpuStatBuilder.java Fri Oct 26 13:12:46 2012 +0200 +++ b/system-backend/src/main/java/com/redhat/thermostat/backend/system/CpuStatBuilder.java Fri Oct 26 13:13:42 2012 +0200 @@ -38,8 +38,6 @@ import java.io.BufferedReader; import java.io.IOException; -import java.util.ArrayList; -import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; @@ -86,13 +84,13 @@ long currentTime = clock.getMonotonicTimeNanos(); long[] currentValues = getCurrentCpuTicks(); - List<Double> cpuUsage = new ArrayList<Double>(currentValues.length); + double[] cpuUsage = new double[currentValues.length]; double timeDelta = (currentTime - previousTime) * 1E-9; for (int i = 0; i < currentValues.length; i++) { long cpuTicksDelta = currentValues[i] - previousCpuTicks[i]; // 100 as in 100 percent. - cpuUsage.add(cpuTicksDelta * (100.0 / timeDelta / ticksPerSecond)); + cpuUsage[i] = cpuTicksDelta * (100.0 / timeDelta / ticksPerSecond); } previousTime = currentTime; previousCpuTicks = currentValues;
--- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/JvmStatHostListener.java Fri Oct 26 13:12:46 2012 +0200 +++ b/system-backend/src/main/java/com/redhat/thermostat/backend/system/JvmStatHostListener.java Fri Oct 26 13:13:42 2012 +0200 @@ -152,7 +152,7 @@ ProcDataSource dataSource = new ProcDataSource(); Map<String, String> environment = new ProcessEnvironmentBuilder(dataSource).build(vmId); // TODO actually figure out the loaded libraries. - List<String> loadedNativeLibraries = new ArrayList<String>(); + String[] loadedNativeLibraries = new String[0]; info = new VmInfo(vmId, startTime, stopTime, extractor.getJavaVersion(), extractor.getJavaHome(), extractor.getMainClass(), extractor.getCommandLine(),
--- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/JvmStatVmListener.java Fri Oct 26 13:12:46 2012 +0200 +++ b/system-backend/src/main/java/com/redhat/thermostat/backend/system/JvmStatVmListener.java Fri Oct 26 13:13:42 2012 +0200 @@ -111,29 +111,29 @@ try { long timestamp = System.currentTimeMillis(); JvmStatDataExtractor extractor = new JvmStatDataExtractor(vm); - long maxGenerations = extractor.getTotalGcGenerations(); - List<Generation> generations = new ArrayList<Generation>(); - VmMemoryStat stat = new VmMemoryStat(timestamp, vmId, generations); - for (long generation = 0; generation < maxGenerations; generation++) { + int maxGenerations = (int) extractor.getTotalGcGenerations(); + Generation[] generations = new Generation[maxGenerations]; + for (int generation = 0; generation < maxGenerations; generation++) { Generation g = new Generation(); - generations.add(g); - g.name = extractor.getGenerationName(generation); - g.capacity = extractor.getGenerationCapacity(generation); - g.maxCapacity = extractor.getGenerationMaxCapacity(generation); - g.collector = extractor.getGenerationCollector(generation); - long maxSpaces = extractor.getTotalSpaces(generation); - List<Space> spaces = new ArrayList<Space>(); - g.spaces = spaces; - for (long space = 0; space < maxSpaces; space++) { + g.setName(extractor.getGenerationName(generation)); + g.setCapacity(extractor.getGenerationCapacity(generation)); + g.setMaxCapacity(extractor.getGenerationMaxCapacity(generation)); + g.setCollector(extractor.getGenerationCollector(generation)); + generations[generation] = g; + int maxSpaces = (int) extractor.getTotalSpaces(generation); + Space[] spaces = new Space[maxSpaces]; + for (int space = 0; space < maxSpaces; space++) { Space s = new Space(); - spaces.add(s); - s.index = (int) space; - s.name = extractor.getSpaceName(generation, space); - s.capacity = extractor.getSpaceCapacity(generation, space); - s.maxCapacity = extractor.getSpaceMaxCapacity(generation, space); - s.used = extractor.getSpaceUsed(generation, space); + s.setIndex((int) space); + s.setName(extractor.getSpaceName(generation, space)); + s.setCapacity(extractor.getSpaceCapacity(generation, space)); + s.setMaxCapacity(extractor.getSpaceMaxCapacity(generation, space)); + s.setUsed(extractor.getSpaceUsed(generation, space)); + spaces[space] = s; } + g.setSpaces(spaces); } + VmMemoryStat stat = new VmMemoryStat(timestamp, vmId, generations); memDAO.putVmMemoryStat(stat); } catch (MonitorException e) { logger.log(Level.WARNING, "error gathering memory info for vm " + vmId, e);
--- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/SystemBackend.java Fri Oct 26 13:12:46 2012 +0200 +++ b/system-backend/src/main/java/com/redhat/thermostat/backend/system/SystemBackend.java Fri Oct 26 13:13:42 2012 +0200 @@ -60,7 +60,6 @@ import com.redhat.thermostat.common.dao.MemoryStatDAO; import com.redhat.thermostat.common.dao.NetworkInterfaceInfoDAO; import com.redhat.thermostat.common.dao.VmCpuStatDAO; -import com.redhat.thermostat.common.model.BackendInformation; import com.redhat.thermostat.common.model.NetworkInterfaceInfo; import com.redhat.thermostat.common.model.VmCpuStat; import com.redhat.thermostat.common.utils.LoggingUtils;
--- a/system-backend/src/test/java/com/redhat/thermostat/backend/system/CpuStatBuilderTest.java Fri Oct 26 13:12:46 2012 +0200 +++ b/system-backend/src/test/java/com/redhat/thermostat/backend/system/CpuStatBuilderTest.java Fri Oct 26 13:13:42 2012 +0200 @@ -106,7 +106,7 @@ CpuStat stat = builder.build(); verify(dataSource, times(2)).getStatReader(); - assertArrayEquals(new double[] {100, 100}, ArrayUtils.toPrimitiveDoubleArray(stat.getPerProcessorUsage()), 0.01); + assertArrayEquals(new double[] {100, 100}, stat.getPerProcessorUsage(), 0.01); } }
--- a/thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/VMCapsSummaryPanel.java Fri Oct 26 13:12:46 2012 +0200 +++ b/thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/VMCapsSummaryPanel.java Fri Oct 26 13:13:42 2012 +0200 @@ -37,7 +37,6 @@ import java.awt.Dimension; import java.awt.GridLayout; -import java.util.List; import javax.swing.DefaultListModel; import javax.swing.JList; @@ -76,7 +75,7 @@ panel.add(list); } - void addInfo(List<String> infos) { + void addInfo(String[] infos) { listModel.removeAllElements(); for (String info : infos) { listModel.addElement(info);
--- a/thread/collector/src/main/java/com/redhat/thermostat/thread/dao/impl/ThreadDaoImpl.java Fri Oct 26 13:12:46 2012 +0200 +++ b/thread/collector/src/main/java/com/redhat/thermostat/thread/dao/impl/ThreadDaoImpl.java Fri Oct 26 13:13:42 2012 +0200 @@ -46,6 +46,7 @@ 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.Update; import com.redhat.thermostat.thread.dao.ThreadDao; import com.redhat.thermostat.thread.model.ThreadInfoData; import com.redhat.thermostat.thread.model.ThreadSummary;
--- a/thread/collector/src/main/java/com/redhat/thermostat/thread/model/VMThreadCapabilities.java Fri Oct 26 13:12:46 2012 +0200 +++ b/thread/collector/src/main/java/com/redhat/thermostat/thread/model/VMThreadCapabilities.java Fri Oct 26 13:13:42 2012 +0200 @@ -36,11 +36,6 @@ package com.redhat.thermostat.thread.model; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - import com.redhat.thermostat.common.model.BasePojo; import com.redhat.thermostat.common.storage.Entity; import com.redhat.thermostat.common.storage.Persist; @@ -49,7 +44,7 @@ @Entity public class VMThreadCapabilities extends BasePojo { - private Set<String> features = new HashSet<>(); + private String[] features; private int vmId; @@ -64,11 +59,11 @@ } public boolean supportCPUTime() { - return features.contains(ThreadDao.CPU_TIME); + return hasFeature(ThreadDao.CPU_TIME); } public boolean supportContentionMonitor() { - return features.contains(ThreadDao.CONTENTION_MONITOR); + return hasFeature(ThreadDao.CONTENTION_MONITOR); } public String toString() { @@ -77,20 +72,26 @@ } public boolean supportThreadAllocatedMemory() { - return features.contains(ThreadDao.THREAD_ALLOCATED_MEMORY); + return hasFeature(ThreadDao.THREAD_ALLOCATED_MEMORY); } - @Persist - public List<String> getSupportedFeaturesList() { - return new ArrayList<>(features); + private boolean hasFeature(String feature) { + for (String f : features) { + if (f.equals(feature)) { + return true; + } + } + return false; } @Persist - public void setSupportedFeaturesList(List<String> featuresList) { - features = new HashSet<>(featuresList); + public String[] getSupportedFeaturesList() { + return features; } - public void addFeature(String feature) { - features.add(feature); + @Persist + public void setSupportedFeaturesList(String[] features) { + this.features = features; } + }
--- a/thread/collector/src/test/java/com/redhat/thermostat/thread/dao/impl/ThreadDaoImplTest.java Fri Oct 26 13:12:46 2012 +0200 +++ b/thread/collector/src/test/java/com/redhat/thermostat/thread/dao/impl/ThreadDaoImplTest.java Fri Oct 26 13:13:42 2012 +0200 @@ -42,13 +42,10 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import java.util.Arrays; - import org.junit.Test; import com.redhat.thermostat.common.dao.HostRef; import com.redhat.thermostat.common.dao.VmRef; -import com.redhat.thermostat.common.storage.Chunk; import com.redhat.thermostat.common.storage.Key; import com.redhat.thermostat.common.storage.Query.Criteria; import com.redhat.thermostat.common.storage.Storage; @@ -82,12 +79,9 @@ when(agent.getAgentId()).thenReturn("0xcafe"); when(ref.getAgent()).thenReturn(agent); - - Chunk answer = mock(Chunk.class); - when(answer.get(ThreadDao.SUPPORTED_FEATURES_LIST_KEY)).thenReturn(Arrays.asList(ThreadDao.CPU_TIME, ThreadDao.THREAD_ALLOCATED_MEMORY)); - + VMThreadCapabilities expected = new VMThreadCapabilities(); - expected.setSupportedFeaturesList(Arrays.asList(ThreadDao.CPU_TIME, ThreadDao.THREAD_ALLOCATED_MEMORY)); + expected.setSupportedFeaturesList(new String[] { ThreadDao.CPU_TIME, ThreadDao.THREAD_ALLOCATED_MEMORY }); when(storage.findPojo(query, VMThreadCapabilities.class)).thenReturn(expected); ThreadDaoImpl dao = new ThreadDaoImpl(storage); @@ -105,10 +99,6 @@ public void testSaveVMCapabilities() { Storage storage = mock(Storage.class); - Chunk answer = mock(Chunk.class); - when(answer.get(ThreadDao.CONTENTION_MONITOR_KEY)).thenReturn(false); - when(answer.get(ThreadDao.CPU_TIME_KEY)).thenReturn(true); - VMThreadCapabilities caps = mock(VMThreadCapabilities.class); when(caps.supportContentionMonitor()).thenReturn(true); when(caps.supportCPUTime()).thenReturn(true);
--- a/thread/harvester/src/main/java/com/redhat/thermostat/thread/harvester/Harvester.java Fri Oct 26 13:12:46 2012 +0200 +++ b/thread/harvester/src/main/java/com/redhat/thermostat/thread/harvester/Harvester.java Fri Oct 26 13:13:42 2012 +0200 @@ -40,6 +40,8 @@ import java.lang.management.ManagementFactory; import java.lang.management.ThreadInfo; import java.lang.management.ThreadMXBean; +import java.util.ArrayList; +import java.util.List; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; @@ -247,20 +249,22 @@ ThreadMXBean bean = getDataCollectorBean(connection); VMThreadCapabilities caps = new VMThreadCapabilities(); + List<String> features = new ArrayList<>(3); if (bean.isThreadCpuTimeSupported()) - caps.addFeature(ThreadDao.CPU_TIME); + features.add(ThreadDao.CPU_TIME); if (bean.isThreadContentionMonitoringSupported()) - caps.addFeature(ThreadDao.CONTENTION_MONITOR); + features.add(ThreadDao.CONTENTION_MONITOR); if (bean instanceof com.sun.management.ThreadMXBean) { com.sun.management.ThreadMXBean sunBean = (com.sun.management.ThreadMXBean) bean; try { if (sunBean.isThreadAllocatedMemorySupported()) { - caps.addFeature(ThreadDao.THREAD_ALLOCATED_MEMORY); + features.add(ThreadDao.THREAD_ALLOCATED_MEMORY); } } catch (Exception ignore) {}; } + caps.setSupportedFeaturesList(features.toArray(new String[features.size()])); caps.setVmId(Integer.parseInt(vmId)); threadDao.saveCapabilities(caps);
--- a/thread/harvester/src/test/java/com/redhat/thermostat/thread/harvester/HarvesterTest.java Fri Oct 26 13:12:46 2012 +0200 +++ b/thread/harvester/src/test/java/com/redhat/thermostat/thread/harvester/HarvesterTest.java Fri Oct 26 13:13:42 2012 +0200 @@ -385,10 +385,9 @@ verify(dao, times(1)).saveCapabilities(any(VMThreadCapabilities.class)); assertEquals(42, capsCapture.getValue().getVmId()); - List<String> features = capsCapture.getValue().getSupportedFeaturesList(); - assertEquals(2, features.size()); - assertTrue(features.contains(ThreadDao.CPU_TIME)); - assertTrue(features.contains(ThreadDao.CONTENTION_MONITOR)); - assertFalse(features.contains(ThreadDao.THREAD_ALLOCATED_MEMORY)); + String[] features = capsCapture.getValue().getSupportedFeaturesList(); + assertEquals(2, features.length); + assertEquals(ThreadDao.CPU_TIME, features[0]); + assertEquals(ThreadDao.CONTENTION_MONITOR, features[1]); } }
--- a/tools/src/main/java/com/redhat/thermostat/tools/cli/VMStatPrinter.java Fri Oct 26 13:12:46 2012 +0200 +++ b/tools/src/main/java/com/redhat/thermostat/tools/cli/VMStatPrinter.java Fri Oct 26 13:13:42 2012 +0200 @@ -41,7 +41,6 @@ import java.text.DecimalFormat; import java.util.Arrays; import java.util.Collections; -import java.util.Comparator; import java.util.Date; import java.util.Iterator; import java.util.List; @@ -161,8 +160,8 @@ } int i = 0; for (VmMemoryStat.Generation gen : vmMemoryStat.getGenerations()) { - for (VmMemoryStat.Space space : gen.spaces) { - String[] displayableSize = DisplayableValues.bytes(space.used); + for (VmMemoryStat.Space space : gen.getSpaces()) { + String[] displayableSize = DisplayableValues.bytes(space.getUsed()); memoryUsage[i] = translator.localize(LocaleResources.VALUE_AND_UNIT, displayableSize[0], displayableSize[1]); i++; } @@ -178,8 +177,8 @@ VmMemoryStat stat = memStats.get(0); int i = 0; for (VmMemoryStat.Generation gen : stat.getGenerations()) { - for (VmMemoryStat.Space space : gen.spaces) { - spacesNames[i] = translator.localize(LocaleResources.COLUMN_HEADER_MEMORY_PATTERN, space.name); + for (VmMemoryStat.Space space : gen.getSpaces()) { + spacesNames[i] = translator.localize(LocaleResources.COLUMN_HEADER_MEMORY_PATTERN, space.getName()); i++; } } @@ -193,7 +192,7 @@ VmMemoryStat stat = memStats.get(0); int numSpaces = 0; for (VmMemoryStat.Generation gen : stat.getGenerations()) { - numSpaces += gen.spaces.size(); + numSpaces += gen.getSpaces().length; } return numSpaces; }
--- a/tools/src/test/java/com/redhat/thermostat/tools/cli/VMInfoCommandTest.java Fri Oct 26 13:12:46 2012 +0200 +++ b/tools/src/test/java/com/redhat/thermostat/tools/cli/VMInfoCommandTest.java Fri Oct 26 13:13:42 2012 +0200 @@ -43,7 +43,6 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.HashMap; @@ -115,7 +114,7 @@ start.set(2012, 5, 7, 15, 32, 0); Calendar end = Calendar.getInstance(); end.set(2013, 10, 1, 1, 22, 0); - VmInfo vmInfo = new VmInfo(234, start.getTimeInMillis(), end.getTimeInMillis(), "vmVersion", "javaHome", "mainClass", "commandLine", "vmName", "vmInfo", "vmVersion", "vmArguments", new HashMap<String,String>(), new HashMap<String,String>(), new ArrayList<String>()); + VmInfo vmInfo = new VmInfo(234, start.getTimeInMillis(), end.getTimeInMillis(), "vmVersion", "javaHome", "mainClass", "commandLine", "vmName", "vmInfo", "vmVersion", "vmArguments", new HashMap<String,String>(), new HashMap<String,String>(), new String[0]); when(vmsDAO.getVmInfo(vm)).thenReturn(vmInfo); when(vmsDAO.getVmInfo(new VmRef(host, 9876, "dummy"))).thenThrow(new DAOException("Unknown VM ID: 9876")); when(vmsDAO.getVMs(host)).thenReturn(Arrays.asList(vm)); @@ -191,7 +190,7 @@ public void testStopTime() throws CommandException { Calendar start = Calendar.getInstance(); start.set(2012, 5, 7, 15, 32, 0); - VmInfo vmInfo = new VmInfo(234, start.getTimeInMillis(), Long.MIN_VALUE, "vmVersion", "javaHome", "mainClass", "commandLine", "vmName", "vmInfo", "vmVersion", "vmArguments", new HashMap<String,String>(), new HashMap<String,String>(), new ArrayList<String>()); + VmInfo vmInfo = new VmInfo(234, start.getTimeInMillis(), Long.MIN_VALUE, "vmVersion", "javaHome", "mainClass", "commandLine", "vmName", "vmInfo", "vmVersion", "vmArguments", new HashMap<String,String>(), new HashMap<String,String>(), new String[0]); when(vmsDAO.getVmInfo(vm)).thenReturn(vmInfo); SimpleArguments args = new SimpleArguments();
--- a/tools/src/test/java/com/redhat/thermostat/tools/cli/VmStatCommandTest.java Fri Oct 26 13:12:46 2012 +0200 +++ b/tools/src/test/java/com/redhat/thermostat/tools/cli/VmStatCommandTest.java Fri Oct 26 13:13:42 2012 +0200 @@ -143,57 +143,57 @@ VmMemoryStat.Space space1_1_1 = newSpace("space1", 123456, 12345, 1, 0); VmMemoryStat.Space space1_1_2 = newSpace("space2", 123456, 12345, 1, 0); - List<VmMemoryStat.Space> spaces1_1 = Arrays.asList(space1_1_1, space1_1_2); + VmMemoryStat.Space[] spaces1_1 = new VmMemoryStat.Space[] { space1_1_1, space1_1_2 }; VmMemoryStat.Generation gen1_1 = newGeneration("gen1", "col1", 123456, 12345, spaces1_1); VmMemoryStat.Space space1_2_1 = newSpace("space3", 123456, 12345, 1, 0); VmMemoryStat.Space space1_2_2 = newSpace("space4", 123456, 12345, 1, 0); - List<VmMemoryStat.Space> spaces1_2 = Arrays.asList(space1_2_1, space1_2_2); + VmMemoryStat.Space[] spaces1_2 = new VmMemoryStat.Space[] { space1_2_1, space1_2_2 }; VmMemoryStat.Generation gen1_2 = newGeneration("gen2", "col1", 123456, 12345, spaces1_2); - List<VmMemoryStat.Generation> gens1 = Arrays.asList(gen1_1, gen1_2); + VmMemoryStat.Generation[] gens1 = new VmMemoryStat.Generation[] { gen1_1, gen1_2 }; VmMemoryStat memStat1 = new VmMemoryStat(1, vmId, gens1); VmMemoryStat.Space space2_1_1 = newSpace("space1", 123456, 12345, 2, 0); VmMemoryStat.Space space2_1_2 = newSpace("space2", 123456, 12345, 2, 0); - List<VmMemoryStat.Space> spaces2_1 = Arrays.asList(space2_1_1, space2_1_2); + VmMemoryStat.Space[] spaces2_1 = new VmMemoryStat.Space[] { space2_1_1, space2_1_2 }; VmMemoryStat.Generation gen2_1 = newGeneration("gen1", "col1", 123456, 12345, spaces2_1); VmMemoryStat.Space space2_2_1 = newSpace("space3", 123456, 12345, 3, 0); VmMemoryStat.Space space2_2_2 = newSpace("space4", 123456, 12345, 4, 0); - List<VmMemoryStat.Space> spaces2_2 = Arrays.asList(space2_2_1, space2_2_2); + VmMemoryStat.Space[] spaces2_2 = new VmMemoryStat.Space[] { space2_2_1, space2_2_2 }; VmMemoryStat.Generation gen2_2 = newGeneration("gen2", "col1", 123456, 12345, spaces2_2); - List<VmMemoryStat.Generation> gens2 = Arrays.asList(gen2_1, gen2_2); + VmMemoryStat.Generation[] gens2 = new VmMemoryStat.Generation[] { gen2_1, gen2_2 }; VmMemoryStat memStat2 = new VmMemoryStat(2, vmId, gens2); VmMemoryStat.Space space3_1_1 = newSpace("space1", 123456, 12345, 4, 0); VmMemoryStat.Space space3_1_2 = newSpace("space2", 123456, 12345, 5, 0); - List<VmMemoryStat.Space> spaces3_1 = Arrays.asList(space3_1_1, space3_1_2); + VmMemoryStat.Space[] spaces3_1 = new VmMemoryStat.Space[] { space3_1_1, space3_1_2 }; VmMemoryStat.Generation gen3_1 = newGeneration("gen1", "col1", 123456, 12345, spaces3_1); VmMemoryStat.Space space3_2_1 = newSpace("space3", 123456, 12345, 6, 0); VmMemoryStat.Space space3_2_2 = newSpace("space4", 123456, 12345, 7, 0); - List<VmMemoryStat.Space> spaces3_2 = Arrays.asList(space3_2_1, space3_2_2); + VmMemoryStat.Space[] spaces3_2 = new VmMemoryStat.Space[] { space3_2_1, space3_2_2 }; VmMemoryStat.Generation gen3_2 = newGeneration("gen2", "col1", 123456, 12345, spaces3_2); - List<VmMemoryStat.Generation> gens3 = Arrays.asList(gen3_1, gen3_2); + VmMemoryStat.Generation[] gens3 = new VmMemoryStat.Generation[] { gen3_1, gen3_2 }; VmMemoryStat memStat3 = new VmMemoryStat(3, vmId, gens3); VmMemoryStat.Space space4_1_1 = newSpace("space1", 123456, 12345, 8, 0); VmMemoryStat.Space space4_1_2 = newSpace("space2", 123456, 12345, 9, 0); - List<VmMemoryStat.Space> spaces4_1 = Arrays.asList(space4_1_1, space4_1_2); + VmMemoryStat.Space[] spaces4_1 = new VmMemoryStat.Space[] { space4_1_1, space4_1_2 }; VmMemoryStat.Generation gen4_1 = newGeneration("gen4", "col1", 123456, 12345, spaces4_1); VmMemoryStat.Space space4_2_1 = newSpace("space3", 123456, 12345, 10, 0); VmMemoryStat.Space space4_2_2 = newSpace("space4", 123456, 12345, 11, 0); - List<VmMemoryStat.Space> spaces4_2 = Arrays.asList(space4_2_1, space4_2_2); + VmMemoryStat.Space[] spaces4_2 = new VmMemoryStat.Space[] { space4_2_1, space4_2_2 }; VmMemoryStat.Generation gen4_2 = newGeneration("gen4", "col1", 123456, 12345, spaces4_2); - List<VmMemoryStat.Generation> gens4 = Arrays.asList(gen4_1, gen4_2); + VmMemoryStat.Generation[] gens4 = new VmMemoryStat.Generation[] { gen4_1, gen4_2 }; VmMemoryStat memStat4 = new VmMemoryStat(4, vmId, gens4); @@ -207,20 +207,20 @@ private Space newSpace(String name, long maxCapacity, long capacity, long used, int index) { VmMemoryStat.Space space = new VmMemoryStat.Space(); - space.name = name; - space.maxCapacity = maxCapacity; - space.capacity = capacity; - space.used = used; - space.index = index; + space.setName(name); + space.setMaxCapacity(maxCapacity); + space.setCapacity(capacity); + space.setUsed(used); + space.setIndex(index); return space; } - private Generation newGeneration(String name, String collector, long maxCapacity, long capacity, List<Space> spaces) { + private Generation newGeneration(String name, String collector, long maxCapacity, long capacity, Space[] spaces) { VmMemoryStat.Generation gen = new VmMemoryStat.Generation(); - gen.name = name; - gen.collector = collector; - gen.maxCapacity = capacity; - gen.spaces = spaces; + gen.setName(name); + gen.setCollector(collector); + gen.setMaxCapacity(capacity); + gen.setSpaces(spaces); return gen; }
--- a/web/client/src/main/java/com/redhat/thermostat/web/client/RESTStorage.java Fri Oct 26 13:12:46 2012 +0200 +++ b/web/client/src/main/java/com/redhat/thermostat/web/client/RESTStorage.java Fri Oct 26 13:13:42 2012 +0200 @@ -65,6 +65,8 @@ import org.apache.http.message.BasicNameValuePair; import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.redhat.thermostat.common.model.AgentIdPojo; import com.redhat.thermostat.common.model.Pojo; import com.redhat.thermostat.common.storage.Category; import com.redhat.thermostat.common.storage.Connection; @@ -74,6 +76,7 @@ import com.redhat.thermostat.common.storage.Storage; import com.redhat.thermostat.common.storage.Update; import com.redhat.thermostat.web.common.RESTQuery; +import com.redhat.thermostat.web.common.ThermostatGSONConverter; import com.redhat.thermostat.web.common.WebInsert; import com.redhat.thermostat.web.common.WebRemove; import com.redhat.thermostat.web.common.WebUpdate; @@ -105,10 +108,12 @@ private UUID agentId; private Map<Category, Integer> categoryIds; + private Gson gson; public RESTStorage() { endpoint = "http://localhost:8082"; categoryIds = new HashMap<>(); + gson = new GsonBuilder().registerTypeHierarchyAdapter(Pojo.class, new ThermostatGSONConverter()).create(); } @Override @@ -122,7 +127,6 @@ conn.setDoInput(true); conn.setRequestMethod("POST"); OutputStream out = conn.getOutputStream(); - Gson gson = new Gson(); OutputStreamWriter writer = new OutputStreamWriter(out); writer.write("name="); writer.write(URLEncoder.encode(category.getName(), enc)); @@ -164,7 +168,6 @@ conn.setDoOutput(true); conn.setRequestMethod("POST"); OutputStream out = conn.getOutputStream(); - Gson gson = new Gson(); OutputStreamWriter writer = new OutputStreamWriter(out); ((RESTQuery) query).setResultClassName(resultClass.getName()); gson.toJson(query, writer); @@ -188,7 +191,6 @@ conn.setDoOutput(true); conn.setRequestMethod("POST"); OutputStream out = conn.getOutputStream(); - Gson gson = new Gson(); OutputStreamWriter writer = new OutputStreamWriter(out); gson.toJson(query, writer); writer.flush(); @@ -220,7 +222,6 @@ conn.setDoOutput(true); conn.setRequestMethod("POST"); OutputStream out = conn.getOutputStream(); - Gson gson = new Gson(); OutputStreamWriter writer = new OutputStreamWriter(out); writer.write("category="); gson.toJson(categoryIds.get(category), writer); @@ -267,7 +268,7 @@ } @Override - public void putPojo(Category category, boolean replace, Pojo pojo) { + public void putPojo(Category category, boolean replace, AgentIdPojo pojo) { // TODO: This logic should probably be moved elsewhere. I.e. out of the Storage API. if (pojo.getAgentId() == null) { pojo.setAgentId(getAgentId()); @@ -281,7 +282,6 @@ conn.setDoInput(true); conn.setRequestMethod("POST"); OutputStream out = conn.getOutputStream(); - Gson gson = new Gson(); OutputStreamWriter writer = new OutputStreamWriter(out); writer.write("insert="); writer.write(URLEncoder.encode(gson.toJson(insert), "UTF-8")); @@ -309,7 +309,6 @@ conn.setDoOutput(true); conn.setRequestMethod("POST"); OutputStream out = conn.getOutputStream(); - Gson gson = new Gson(); OutputStreamWriter writer = new OutputStreamWriter(out); writer.write("remove="); writer.write(URLEncoder.encode(gson.toJson(remove), "UTF-8")); @@ -354,7 +353,6 @@ conn.setDoInput(true); conn.setRequestMethod("POST"); OutputStream out = conn.getOutputStream(); - Gson gson = new Gson(); OutputStreamWriter writer = new OutputStreamWriter(out); writer.write("update="); writer.write(URLEncoder.encode(gson.toJson(webUp), "UTF-8"));
--- a/web/client/src/main/java/com/redhat/thermostat/web/client/WebCursor.java Fri Oct 26 13:12:46 2012 +0200 +++ b/web/client/src/main/java/com/redhat/thermostat/web/client/WebCursor.java Fri Oct 26 13:13:42 2012 +0200 @@ -37,10 +37,8 @@ package com.redhat.thermostat.web.client; -import com.redhat.thermostat.common.NotImplementedException; import com.redhat.thermostat.common.model.Pojo; import com.redhat.thermostat.common.storage.Cursor; -import com.redhat.thermostat.common.storage.Key; class WebCursor<T extends Pojo> implements Cursor<T> {
--- a/web/client/src/test/java/com/redhat/thermostat/web/client/TestObj.java Fri Oct 26 13:12:46 2012 +0200 +++ b/web/client/src/test/java/com/redhat/thermostat/web/client/TestObj.java Fri Oct 26 13:13:42 2012 +0200 @@ -38,16 +38,21 @@ package com.redhat.thermostat.web.client; import com.redhat.thermostat.common.model.BasePojo; +import com.redhat.thermostat.common.storage.Entity; +import com.redhat.thermostat.common.storage.Persist; +@Entity public class TestObj extends BasePojo { private String property1; + @Persist public void setProperty1(String property1) { this.property1 = property1; } + @Persist public String getProperty1() { return property1; }
--- a/web/common/pom.xml Fri Oct 26 13:12:46 2012 +0200 +++ b/web/common/pom.xml Fri Oct 26 13:13:42 2012 +0200 @@ -59,6 +59,12 @@ </dependency> <dependency> + <groupId>com.google.code.gson</groupId> + <artifactId>gson</artifactId> + <version>2.2.2</version> + </dependency> + + <dependency> <groupId>com.redhat.thermostat</groupId> <artifactId>thermostat-common-core</artifactId> <version>${project.version}</version>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/web/common/src/main/java/com/redhat/thermostat/web/common/ThermostatGSONConverter.java Fri Oct 26 13:13:42 2012 +0200 @@ -0,0 +1,110 @@ +/* + * 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.web.common; + +import java.beans.PropertyDescriptor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Type; + +import org.apache.commons.beanutils.PropertyUtils; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; +import com.redhat.thermostat.common.model.Pojo; +import com.redhat.thermostat.common.storage.Entity; +import com.redhat.thermostat.common.storage.Persist; + +public class ThermostatGSONConverter implements JsonSerializer<Pojo>, JsonDeserializer<Pojo> { + + @Override + public Pojo deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { + @SuppressWarnings("unchecked") + Class<? extends Pojo> targetType = (Class<Pojo>) typeOfT; + try { + Pojo pojo = targetType.newInstance(); + PropertyDescriptor[] descs = PropertyUtils.getPropertyDescriptors(pojo); + for (PropertyDescriptor desc : descs) { + Method writeMethod = desc.getWriteMethod(); + if (writeMethod != null && writeMethod.isAnnotationPresent(Persist.class)) { + String name = desc.getName(); + JsonElement child = json.getAsJsonObject().get(name); + Object value = context.deserialize(child, desc.getPropertyType()); + PropertyUtils.setProperty(pojo, name, value); + } + } + return pojo; + } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { + throw new RuntimeException(e); + } + } + + @Override + public JsonElement serialize(Pojo src, Type typeOfSrc, JsonSerializationContext context) { + Class cls = (Class) typeOfSrc; + if (! cls.isAnnotationPresent(Entity.class)) { + System.err.println("attempt to serialize non-Entity class: " + cls.getName()); + throw new IllegalArgumentException("attempt to serialize non-Entity class: " + cls.getName()); + } + JsonObject obj = new JsonObject(); + PropertyDescriptor[] descs = PropertyUtils.getPropertyDescriptors(src); + for (PropertyDescriptor desc : descs) { + Method readMethod = desc.getReadMethod(); + if (readMethod != null && readMethod.isAnnotationPresent(Persist.class)) { + String name = desc.getName(); + + try { + Object value = PropertyUtils.getProperty(src, name); + obj.add(name, context.serialize(value)); + } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { + throw new RuntimeException(e); + } + } else if (readMethod == null) { + System.err.println("WARNING: property without read method: " + src.getClass().getName() + "::" + desc.getName()); + } + } + return obj; + } + + +}
--- a/web/common/src/main/java/com/redhat/thermostat/web/common/WebInsert.java Fri Oct 26 13:12:46 2012 +0200 +++ b/web/common/src/main/java/com/redhat/thermostat/web/common/WebInsert.java Fri Oct 26 13:13:42 2012 +0200 @@ -62,6 +62,14 @@ this.categoryId = categoryId; } + public String getPojoClass() { + return pojoClass; + } + + public void setPojoClass(String pojoClass) { + this.pojoClass = pojoClass; + } + public boolean isReplace() { return replace; } @@ -70,13 +78,5 @@ this.replace = replace; } - public String getPojoClass() { - return pojoClass; - } - - public void setPojoClass(String pojoClass) { - this.pojoClass = pojoClass; - } - }
--- a/web/common/src/main/java/com/redhat/thermostat/web/common/WebUpdate.java Fri Oct 26 13:12:46 2012 +0200 +++ b/web/common/src/main/java/com/redhat/thermostat/web/common/WebUpdate.java Fri Oct 26 13:13:42 2012 +0200 @@ -42,8 +42,8 @@ import com.redhat.thermostat.common.storage.Category; import com.redhat.thermostat.common.storage.Key; +import com.redhat.thermostat.common.storage.Query.Criteria; import com.redhat.thermostat.common.storage.Update; -import com.redhat.thermostat.common.storage.Query.Criteria; public class WebUpdate implements Update { @@ -135,4 +135,5 @@ public List<WebUpdate.UpdateValue> getUpdates() { return updateValues; } + }
--- a/web/server/src/main/java/com/redhat/thermostat/web/server/RESTStorageEndPoint.java Fri Oct 26 13:12:46 2012 +0200 +++ b/web/server/src/main/java/com/redhat/thermostat/web/server/RESTStorageEndPoint.java Fri Oct 26 13:13:42 2012 +0200 @@ -22,8 +22,10 @@ import org.apache.commons.fileupload.servlet.ServletFileUpload; import com.google.gson.Gson; +import com.google.gson.GsonBuilder; import com.google.gson.JsonArray; import com.google.gson.JsonParser; +import com.redhat.thermostat.common.model.AgentIdPojo; import com.redhat.thermostat.common.model.Pojo; import com.redhat.thermostat.common.storage.Category; import com.redhat.thermostat.common.storage.Cursor; @@ -36,6 +38,7 @@ import com.redhat.thermostat.web.common.Qualifier; import com.redhat.thermostat.web.common.RESTQuery; import com.redhat.thermostat.web.common.StorageWrapper; +import com.redhat.thermostat.web.common.ThermostatGSONConverter; import com.redhat.thermostat.web.common.WebInsert; import com.redhat.thermostat.web.common.WebRemove; import com.redhat.thermostat.web.common.WebUpdate; @@ -52,7 +55,7 @@ private Map<Integer, Category> categories; public void init() { - gson = new Gson(); + gson = new GsonBuilder().registerTypeHierarchyAdapter(Pojo.class, new ThermostatGSONConverter()).create(); categoryIds = new HashMap<>(); categories = new HashMap<>(); } @@ -174,9 +177,9 @@ try { String insertParam = req.getParameter("insert"); WebInsert insert = gson.fromJson(insertParam, WebInsert.class); - Class<? extends Pojo> pojoCls = (Class<? extends Pojo>) Class.forName(insert.getPojoClass()); + Class<? extends AgentIdPojo> pojoCls = (Class<? extends AgentIdPojo>) Class.forName(insert.getPojoClass()); String pojoParam = req.getParameter("pojo"); - Pojo pojo = gson.fromJson(pojoParam, pojoCls); + AgentIdPojo pojo = gson.fromJson(pojoParam, pojoCls); int categoryId = insert.getCategoryId(); Category category = getCategoryFromId(categoryId); storage.putPojo(category, insert.isReplace(), pojo); @@ -213,17 +216,22 @@ assert (qualifier.getCriteria() == Criteria.EQUALS); targetUpdate = targetUpdate.where(qualifier.getKey(), qualifier.getValue()); } - String valuesParam = req.getParameter("values"); - JsonParser parser = new JsonParser(); - JsonArray jsonArray = parser.parse(valuesParam).getAsJsonArray(); List<WebUpdate.UpdateValue> updates = update.getUpdates(); - int index = 0; - for (WebUpdate.UpdateValue updateValue : updates) { - Class valueClass = Class.forName(updateValue.getValueClass()); - Object value = gson.fromJson(jsonArray.get(index), valueClass); - index++; - Key key = updateValue.getKey(); - targetUpdate.set(key, value); + if (updates != null) { + String valuesParam = req.getParameter("values"); + JsonParser parser = new JsonParser(); + JsonArray jsonArray = parser.parse(valuesParam) + .getAsJsonArray(); + int index = 0; + for (WebUpdate.UpdateValue updateValue : updates) { + Class valueClass = Class.forName(updateValue + .getValueClass()); + Object value = gson.fromJson(jsonArray.get(index), + valueClass); + index++; + Key key = updateValue.getKey(); + targetUpdate.set(key, value); + } } storage.updatePojo(targetUpdate); resp.setStatus(HttpServletResponse.SC_OK);
--- a/web/server/src/test/java/com/redhat/thermostat/web/server/RESTStorageEndpointTest.java Fri Oct 26 13:12:46 2012 +0200 +++ b/web/server/src/test/java/com/redhat/thermostat/web/server/RESTStorageEndpointTest.java Fri Oct 26 13:13:42 2012 +0200 @@ -72,7 +72,9 @@ import com.redhat.thermostat.common.storage.Categories; import com.redhat.thermostat.common.storage.Category; import com.redhat.thermostat.common.storage.Cursor; +import com.redhat.thermostat.common.storage.Entity; import com.redhat.thermostat.common.storage.Key; +import com.redhat.thermostat.common.storage.Persist; import com.redhat.thermostat.common.storage.Query; import com.redhat.thermostat.common.storage.Query.Criteria; import com.redhat.thermostat.common.storage.Remove; @@ -89,18 +91,23 @@ public class RESTStorageEndpointTest { + @Entity public static class TestClass extends BasePojo { private String key1; private int key2; + @Persist public String getKey1() { return key1; } + @Persist public void setKey1(String key1) { this.key1 = key1; } + @Persist public int getKey2() { return key2; } + @Persist public void setKey2(int key2) { this.key2 = key2; }