Mercurial > hg > release > thermostat-1.6
changeset 1909:323e9c6e2192
Complete vm-numa plugin.
This is a backport of the vm-numa plugin from the hg/thermostat repository
revision fd3632b6449c. This changeset is built on top of revision
cb6390cf824b and completes the backport for the vm-numa plugin. The
separation is to make it easier to see relevant changes for the vm-numa
plugin.
PR3007
Reviewed-by: jerboaa
Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2016-June/019313.html
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/experimental/ThermostatChartPanel.java Thu Jun 09 09:32:01 2016 -0400 @@ -0,0 +1,233 @@ +/* + * Copyright 2012-2016 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.client.swing.components.experimental; + +import java.awt.BasicStroke; +import java.awt.BorderLayout; +import java.awt.Color; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.ArrayList; +import java.util.List; +import javax.swing.BoxLayout; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; +import javax.swing.text.JTextComponent; + +import org.jfree.chart.ChartMouseEvent; +import org.jfree.chart.ChartMouseListener; +import org.jfree.chart.ChartPanel; +import org.jfree.chart.JFreeChart; +import org.jfree.chart.axis.ValueAxis; +import org.jfree.chart.panel.CrosshairOverlay; +import org.jfree.chart.plot.Crosshair; +import org.jfree.chart.plot.XYPlot; +import org.jfree.ui.RectangleEdge; + +import com.redhat.thermostat.client.core.experimental.Duration; +import com.redhat.thermostat.client.swing.components.ValueField; +import com.redhat.thermostat.client.ui.SampledDataset; + + +public class ThermostatChartPanel extends JPanel { + + public static final String PROPERTY_VISIBLE_TIME_RANGE = "visibleTimeRange"; + + private static final Color WHITE = new Color(255,255,255,0); + private static final Color BLACK = new Color(0,0,0,0); + private static final float TRANSPARENT = 0.0f; + + private static final int MINIMUM_DRAW_SIZE = 100; + + private JPanel chartsPanel; + private List<ChartPanel> charts; + + private RecentTimeControlPanel recentTimeControlPanel; + private JTextComponent label; + + private Duration initialDuration; + + private ChartPanel chartPanel; + private Crosshair xCrosshair; + + public ThermostatChartPanel(JFreeChart chart, Duration initialDuration) { + this(initialDuration); + + addChart(chart); + } + + public ThermostatChartPanel(Duration initialDuration) { + this.initialDuration = initialDuration; + this.chartsPanel = new JPanel(); + this.charts = new ArrayList<>(); + + chartsPanel.setLayout(new BoxLayout(chartsPanel, BoxLayout.Y_AXIS)); + + this.setLayout(new BorderLayout()); + + recentTimeControlPanel = new RecentTimeControlPanel(initialDuration); + recentTimeControlPanel.addPropertyChangeListener(RecentTimeControlPanel.PROPERTY_VISIBLE_TIME_RANGE, new PropertyChangeListener() { + @Override + public void propertyChange(final PropertyChangeEvent evt) { + Duration d = (Duration) evt.getNewValue(); + ThermostatChartPanel.this.firePropertyChange(RecentTimeControlPanel.PROPERTY_VISIBLE_TIME_RANGE, null, d); + } + }); + + add(chartsPanel, BorderLayout.CENTER); + add(recentTimeControlPanel, BorderLayout.SOUTH); + + revalidate(); + } + + public void addChart(JFreeChart chart) { + // jfreechart still generates tooltips when disabled, prevent generation as well + if (chart.getPlot() instanceof XYPlot) { + chart.getXYPlot().getRenderer().setBaseToolTipGenerator(null); + } + + chart.getXYPlot().getRangeAxis().setAutoRange(true); + + chart.getXYPlot().getDomainAxis().setAutoRange(true); + chart.getXYPlot().getDomainAxis().setFixedAutoRange(initialDuration.unit.toMillis(initialDuration.value)); + + chart.getPlot().setBackgroundPaint(WHITE); + chart.getPlot().setBackgroundImageAlpha(TRANSPARENT); + chart.getPlot().setOutlinePaint(BLACK); + + chartPanel = new ChartPanel(chart); + + chartPanel.setDisplayToolTips(false); + chartPanel.setDoubleBuffered(true); + chartPanel.setMouseZoomable(false); + chartPanel.setPopupMenu(null); + + /* + * By default, ChartPanel scales itself instead of redrawing things when + * it's resized. To have it resize automatically, we need to set minimum + * and maximum sizes. Lets constrain the minimum, but not the maximum + * size. + */ + chartPanel.setMinimumDrawHeight(MINIMUM_DRAW_SIZE); + chartPanel.setMaximumDrawHeight(Integer.MAX_VALUE); + chartPanel.setMinimumDrawWidth(MINIMUM_DRAW_SIZE); + chartPanel.setMaximumDrawWidth(Integer.MAX_VALUE); + + chartsPanel.add(chartPanel); + chartsPanel.revalidate(); + charts.add(chartPanel); + + } + + public void setTimeRangeToShow(Duration duration) { + for (ChartPanel cp : charts) { + XYPlot plot = cp.getChart().getXYPlot(); + + // Don't drop old data; just dont' show it. + plot.getDomainAxis().setAutoRange(true); + plot.getDomainAxis().setFixedAutoRange(initialDuration.unit.toMillis(initialDuration.value)); + } + } + + public void setDataInformationLabel(final String text) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + if (label == null) { + label = new ValueField(text); + recentTimeControlPanel.addTextComponent(label); + } + + label.setName("crossHair"); + label.setText(text); + } + }); + } + + public void enableDynamicCrosshairs() { + CrosshairOverlay crosshairOverlay = new CrosshairOverlay(); + xCrosshair = new Crosshair(Double.NaN, Color.GRAY, new BasicStroke(0f)); + crosshairOverlay.addDomainCrosshair(xCrosshair); + chartPanel.addOverlay(crosshairOverlay); + + chartPanel.addChartMouseListener(new ChartMouseListener() { + @Override + public void chartMouseClicked(ChartMouseEvent chartMouseEvent) { + //do nothing + } + + @Override + public void chartMouseMoved(ChartMouseEvent event) { + XYPlot plot = (XYPlot) event.getChart().getPlot(); + ValueAxis xAxis = plot.getDomainAxis(); + SampledDataset dataset = (SampledDataset) plot.getDataset(); + double xVal = xAxis.java2DToValue(event.getTrigger().getX(), chartPanel.getScreenDataArea(), RectangleEdge.BOTTOM); + int item = findNearestItem(dataset, xVal); + int series = dataset.getSeriesCount() - 1; + if (item >= 0) { + double x = ((dataset.getStartXValue(series, item) + dataset.getEndXValue(series, item)) / 2) ; + double y = dataset.getYValue(series, item); + xCrosshair.setValue(x); + setDataInformationLabel(String.valueOf(y)); + } else { + xCrosshair.setValue(Double.NaN); + setDataInformationLabel(""); + } + } + }); + } + + private int findNearestItem(SampledDataset dataset, double xValue) { + int series = dataset.getSeriesCount() - 1; + int item = -1; + double currDiff = Math.abs(((dataset.getStartXValue(series, 0) + dataset.getEndXValue(series, 0)) / 2) - xValue); + + for (int i = 0; i < dataset.getItemCount(series); i++) { + double newXVal = (dataset.getStartXValue(series, i) + dataset.getEndXValue(series, i)) / 2; + double newDiff = Math.abs(newXVal - xValue); + double yVal = dataset.getYValue(series, i); + if (newDiff <= currDiff && yVal > 0) { + item = i; + currDiff = newDiff; + } + } + + return item; + } + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/experimental/ThermostatChartPanelTest.java Thu Jun 09 09:32:01 2016 -0400 @@ -0,0 +1,213 @@ +/* + * Copyright 2012-2016 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.client.swing.components.experimental; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertTrue; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.concurrent.TimeUnit; +import javax.swing.JFrame; + +import org.fest.swing.annotation.GUITest; +import org.fest.swing.edt.FailOnThreadViolationRepaintManager; +import org.fest.swing.edt.GuiActionRunner; +import org.fest.swing.edt.GuiTask; +import org.fest.swing.fixture.FrameFixture; +import org.jfree.chart.ChartFactory; +import org.jfree.chart.JFreeChart; +import org.jfree.data.time.TimeSeriesCollection; +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.runner.RunWith; + +import com.redhat.thermostat.annotations.internal.CacioTest; +import com.redhat.thermostat.client.core.experimental.Duration; +import net.java.openjdk.cacio.ctc.junit.CacioFESTRunner; + +@Category(CacioTest.class) +@RunWith(CacioFESTRunner.class) +public class ThermostatChartPanelTest { + + private ThermostatChartPanel thermostatChartPanel; + private final TimeSeriesCollection dataset = new TimeSeriesCollection(); + private Duration duration; + private JFreeChart chart; + private static final int DEFAULT_VALUE = 10; + private static final TimeUnit DEFAULT_UNIT = TimeUnit.MINUTES; + private final int ESCAPE = 27; + + private JFrame frame; + private FrameFixture frameFixture; + + @BeforeClass + public static void setupOnce() { + FailOnThreadViolationRepaintManager.install(); + } + + @Before + public void setUp() { + chart = ChartFactory.createTimeSeriesChart( + null, + "Time Label", + "Value Label", + dataset, + false, false, false); + duration = new Duration(DEFAULT_VALUE, DEFAULT_UNIT); + GuiActionRunner.execute(new GuiTask() { + @Override + protected void executeInEDT() throws Throwable { + thermostatChartPanel = new ThermostatChartPanel(chart, duration); + frame = new JFrame(); + frame.add(thermostatChartPanel); + } + }); + frameFixture = new FrameFixture(frame); + frameFixture.show(); + } + + @After + public void tearDown() { + thermostatChartPanel = null; + duration = null; + frameFixture.cleanUp(); + frameFixture = null; + } + + @GUITest + @Test + public void testDurationChangeFiresPropertyChange() { + + final boolean[] b = new boolean[] {false}; + + thermostatChartPanel.addPropertyChangeListener(ThermostatChartPanel.PROPERTY_VISIBLE_TIME_RANGE, new PropertyChangeListener() { + @Override + public void propertyChange(final PropertyChangeEvent evt) { + Duration d = (Duration) evt.getNewValue(); + Duration expected = new Duration(5, TimeUnit.MINUTES); + if (d.equals(expected)) { + b[0] = true; + } + } + }); + + frameFixture.textBox("durationSelector").selectAll(); + frameFixture.textBox("durationSelector").enterText("5"); + frameFixture.textBox("durationSelector").pressKey(ESCAPE); + assertTrue(b[0]); + } + + @GUITest + @Test + public void testTimeUnitChangeFiresPropertyChange() { + + final boolean[] b = new boolean[] {false}; + + thermostatChartPanel.addPropertyChangeListener(ThermostatChartPanel.PROPERTY_VISIBLE_TIME_RANGE, new PropertyChangeListener() { + @Override + public void propertyChange(final PropertyChangeEvent evt) { + Duration d = (Duration) evt.getNewValue(); + Duration expected = new Duration(10, TimeUnit.HOURS); + if (d.equals(expected)) { + b[0] = true; + } + } + }); + + frameFixture.comboBox("unitSelector").selectItem(1); + + assertTrue(b[0]); + } + + @GUITest + @Test + public void testTimeRangeToShow() { + Duration time = new Duration(20, TimeUnit.MINUTES); + thermostatChartPanel.setTimeRangeToShow(time); + assertEquals(time.unit.toMillis(time.value), (long) chart.getXYPlot().getDomainAxis().getRange().getLength()); + } + + @GUITest + @Test + public void testMultipleChartTimeRangeToShow() { + final JFreeChart chart2 = ChartFactory.createTimeSeriesChart( + null, + "Time Label", + "Value Label", + dataset, + false, false, false); + final JFreeChart chart3 = ChartFactory.createTimeSeriesChart( + null, + "Time Label", + "Value Label", + dataset, + false, false, false); + GuiActionRunner.execute(new GuiTask() { + @Override + protected void executeInEDT() throws Throwable { + thermostatChartPanel.addChart(chart2); + thermostatChartPanel.addChart(chart3); + } + }); + + Duration time = new Duration(20, TimeUnit.MINUTES); + thermostatChartPanel.setTimeRangeToShow(time); + + assertEquals(time.unit.toMillis(time.value), (long) chart.getXYPlot().getDomainAxis().getRange().getLength()); + assertEquals(time.unit.toMillis(time.value), (long) chart2.getXYPlot().getDomainAxis().getRange().getLength()); + assertEquals(time.unit.toMillis(time.value), (long) chart3.getXYPlot().getDomainAxis().getRange().getLength()); + } + + @GUITest + @Test + public void testInitialTimeValue() { + Duration time = new Duration(10, TimeUnit.MINUTES); + assertEquals(time.unit.toMillis(time.value), (long) chart.getXYPlot().getDomainAxis().getRange().getLength()); + } + + @GUITest + @Test + public void testSetDataInformationLabel() { + thermostatChartPanel.setDataInformationLabel("15"); + assertEquals("15", frameFixture.textBox("crossHair").text()); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/test/src/main/java/com/redhat/thermostat/testutils/DataObjectTest.java Thu Jun 09 09:32:01 2016 -0400 @@ -0,0 +1,75 @@ +/* + * Copyright 2012-2016 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.testutils; + +import static org.junit.Assert.assertEquals; + +import java.lang.reflect.Modifier; +import java.util.ArrayList; + +import org.junit.Test; + +public abstract class DataObjectTest { + + @Test + public void testBasicInstantiation() { + ArrayList<Class<?>> failureClasses = new ArrayList<>(); + for (Class<?> clazz : getDataClasses()) { + try { + // pojo converters use this + clazz.newInstance(); + + // pojo converters fail at runtime if the constructor is not public + if (!Modifier.isPublic(clazz.getConstructor().getModifiers())) { + throw new IllegalAccessError("constructor is not public"); + } + } catch (ReflectiveOperationException e) { + failureClasses.add(clazz); + } + } + String msg = "Should be able to instantiate class using no-arg constructor: " + + failureClasses; + assertEquals(msg, 0, failureClasses.size()); + } + + /** + * Returns a list of classes representing data objects. These classes are + * checked to make sure they comply with the requirements for use as + * data-storage objects. + */ + public abstract Class<?>[] getDataClasses(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/test/src/main/java/com/redhat/thermostat/testutils/ServiceLoaderTest.java Thu Jun 09 09:32:01 2016 -0400 @@ -0,0 +1,115 @@ +/* + * Copyright 2012-2016 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.testutils; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.ServiceLoader; + +import org.junit.Test; + +public abstract class ServiceLoaderTest<T> { + + public static final int NO_EXTRA_SERVICES = 0; + public static final int STORAGE_SERVICES = 1; + + private final int extraServices; + private final Class<T> interfaceClass; + private final List<Class<? extends T>> implementations; + + /** + * @param type + * the type of service, such as CategoryRegistration + * @param extraServices + * the number of extra services. See the various *_SERVICES + * constants. + * @param implementations + * the implementations that are expected to be present. This is + * not exclusive; additional services may be present. + */ + @SafeVarargs + public ServiceLoaderTest(Class<T> type, int extraServices, Class<? extends T>... implementations) { + if (implementations == null || implementations.length == 0) { + throw new IllegalArgumentException("implementations is empty"); + } + this.extraServices = extraServices; + this.interfaceClass = type; + this.implementations = Arrays.asList(implementations); + } + + /* + * The web storage end-point uses service loader in order to determine the + * list of trusted/known categories/statements. This test is to ensure + * service loading works for this module's regs. E.g. renaming of the impl + * class without changing + * META-INF/com.redhat.thermostat.storage.core.auth.CategoryRegistration + */ + @Test + public void serviceLoaderCanLoadService() { + Map<String, Boolean> foundServiceNames = new HashMap<>(); + Class<? extends T> firstClass = implementations.get(0); + Collection<String> expectedClassNames = new HashSet<>(); + + for (Class<? extends T> klass : implementations) { + expectedClassNames.add(klass.getName()); + } + + ServiceLoader<T> loader = ServiceLoader.load(this.interfaceClass, firstClass.getClassLoader()); + + List<T> registrations = new ArrayList<>(1); + for (T r: loader) { + foundServiceNames.put(r.getClass().getName(), true); + registrations.add(r); + } + + for (String className : expectedClassNames) { + assertTrue(foundServiceNames.containsKey(className)); + } + + int expectedServicesCount = this.extraServices + implementations.size(); + assertEquals(registrations.size(), expectedServicesCount); + } + +}
--- a/vm-numa/client-core/src/main/java/com/redhat/thermostat/vm/numa/client/core/VmNumaServiceImpl.java Thu Jun 09 08:58:57 2016 -0400 +++ b/vm-numa/client-core/src/main/java/com/redhat/thermostat/vm/numa/client/core/VmNumaServiceImpl.java Thu Jun 09 09:32:01 2016 -0400 @@ -41,8 +41,6 @@ import com.redhat.thermostat.common.ApplicationService; import com.redhat.thermostat.common.Filter; import com.redhat.thermostat.numa.common.NumaDAO; -import com.redhat.thermostat.storage.core.AgentId; -import com.redhat.thermostat.storage.core.VmId; import com.redhat.thermostat.storage.core.VmRef; import com.redhat.thermostat.vm.numa.client.core.internal.VmNumaController; import com.redhat.thermostat.vm.numa.common.VmNumaDAO; @@ -71,9 +69,7 @@ @Override public InformationServiceController<VmRef> getInformationServiceController(VmRef ref) { - VmId vmId = new VmId(ref.getVmId()); - AgentId agentId = new AgentId(ref.getHostRef().getAgentId()); - return new VmNumaController(appSvc, numaDAO, vmNumaDAO, vmId, agentId, vmNumaViewProvider); + return new VmNumaController(appSvc, numaDAO, vmNumaDAO, ref, vmNumaViewProvider); } @Override
--- a/vm-numa/client-core/src/main/java/com/redhat/thermostat/vm/numa/client/core/VmNumaView.java Thu Jun 09 08:58:57 2016 -0400 +++ b/vm-numa/client-core/src/main/java/com/redhat/thermostat/vm/numa/client/core/VmNumaView.java Thu Jun 09 09:32:01 2016 -0400 @@ -36,12 +36,10 @@ package com.redhat.thermostat.vm.numa.client.core; -import java.util.concurrent.TimeUnit; - +import com.redhat.thermostat.client.core.experimental.Duration; import com.redhat.thermostat.client.core.views.BasicView; import com.redhat.thermostat.client.core.views.UIComponent; import com.redhat.thermostat.common.ActionListener; -import com.redhat.thermostat.common.Duration; import com.redhat.thermostat.storage.model.DiscreteTimeData; public abstract class VmNumaView extends BasicView implements UIComponent {
--- a/vm-numa/client-core/src/main/java/com/redhat/thermostat/vm/numa/client/core/internal/VmNumaController.java Thu Jun 09 08:58:57 2016 -0400 +++ b/vm-numa/client-core/src/main/java/com/redhat/thermostat/vm/numa/client/core/internal/VmNumaController.java Thu Jun 09 09:32:01 2016 -0400 @@ -40,19 +40,16 @@ import java.util.concurrent.TimeUnit; import com.redhat.thermostat.client.core.controllers.InformationServiceController; +import com.redhat.thermostat.client.core.experimental.Duration; import com.redhat.thermostat.client.core.views.BasicView; import com.redhat.thermostat.client.core.views.UIComponent; import com.redhat.thermostat.common.ActionEvent; import com.redhat.thermostat.common.ActionListener; import com.redhat.thermostat.common.ApplicationService; -import com.redhat.thermostat.common.Duration; import com.redhat.thermostat.common.Timer; import com.redhat.thermostat.numa.common.NumaDAO; import com.redhat.thermostat.shared.locale.LocalizedString; import com.redhat.thermostat.shared.locale.Translate; -import com.redhat.thermostat.storage.core.AgentId; -import com.redhat.thermostat.storage.core.HostRef; -import com.redhat.thermostat.storage.core.VmId; import com.redhat.thermostat.storage.core.VmRef; import com.redhat.thermostat.storage.model.DiscreteTimeData; import com.redhat.thermostat.vm.numa.client.core.VmNumaView; @@ -69,19 +66,17 @@ private VmNumaView view; - private VmId vmId; - private AgentId agentId; + private VmRef vmRef; private VmNumaDAO vmNumaDAO; private long lastSeenTimestamp = Long.MIN_VALUE; - public VmNumaController(ApplicationService appSvc, NumaDAO numaDAO, VmNumaDAO vmNumaDAO, VmId vmId, AgentId agentId, VmNumaViewProvider vmNumaViewProvider) { - this.vmId = vmId; - this.agentId = agentId; + public VmNumaController(ApplicationService appSvc, NumaDAO numaDAO, VmNumaDAO vmNumaDAO, VmRef vmRef, VmNumaViewProvider vmNumaViewProvider) { + this.vmRef = vmRef; this.vmNumaDAO = vmNumaDAO; - int numNumaNodes = numaDAO.getNumberOfNumaNodes(new HostRef(agentId.get(), "")); + int numNumaNodes = numaDAO.getNumberOfNumaNodes(vmRef.getHostRef()); this.view = vmNumaViewProvider.createView(); @@ -98,7 +93,7 @@ switch (actionEvent.getActionId()) { case USER_CHANGED_TIME_RANGE: Duration duration = view.getUserDesiredDuration(); - lastSeenTimestamp = System.currentTimeMillis() - duration.asMilliseconds(); + lastSeenTimestamp = System.currentTimeMillis() - duration.unit.toMillis(duration.value); view.setVisibleDataRange(duration); break; default: @@ -142,7 +137,7 @@ } private void updateData() { - List<VmNumaStat> stats = vmNumaDAO.getNumaStats(agentId, vmId, lastSeenTimestamp, System.currentTimeMillis()); + List<VmNumaStat> stats = vmNumaDAO.getNumaStats(vmRef, lastSeenTimestamp, System.currentTimeMillis()); if (stats.size() > 0) { lastSeenTimestamp = stats.get(stats.size() - 1).getTimeStamp();
--- a/vm-numa/client-core/src/test/java/com/redhat/thermostat/vm/numa/client/core/internal/VmNumaControllerTest.java Thu Jun 09 08:58:57 2016 -0400 +++ b/vm-numa/client-core/src/test/java/com/redhat/thermostat/vm/numa/client/core/internal/VmNumaControllerTest.java Thu Jun 09 09:32:01 2016 -0400 @@ -38,7 +38,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyLong; import static org.mockito.Matchers.eq; @@ -64,9 +63,8 @@ import com.redhat.thermostat.common.Timer; import com.redhat.thermostat.common.TimerFactory; import com.redhat.thermostat.numa.common.NumaDAO; -import com.redhat.thermostat.storage.core.AgentId; import com.redhat.thermostat.storage.core.HostRef; -import com.redhat.thermostat.storage.core.VmId; +import com.redhat.thermostat.storage.core.VmRef; import com.redhat.thermostat.storage.model.DiscreteTimeData; import com.redhat.thermostat.vm.numa.client.core.VmNumaView; import com.redhat.thermostat.vm.numa.client.core.VmNumaViewProvider; @@ -98,13 +96,13 @@ when(timerFactory.createTimer()).thenReturn(timer); when(appSvc.getTimerFactory()).thenReturn(timerFactory); - AgentId agentId = new AgentId("agent"); - VmId vmId = new VmId("vm"); + HostRef hostRef = new HostRef("host", "host"); + VmRef vmRef = new VmRef(hostRef, "vm", 0, "vm"); NumaDAO numaDAO = mock(NumaDAO.class); when(numaDAO.getNumberOfNumaNodes(any(HostRef.class))).thenReturn(NUM_NODES); VmNumaDAO vmNumaDAO = mock(VmNumaDAO.class); - when(vmNumaDAO.getNumaStats(eq(agentId), eq(vmId), anyLong(), anyLong())).thenReturn(createStats()); + when(vmNumaDAO.getNumaStats(any(VmRef.class), anyLong(), anyLong())).thenReturn(createStats()); VmNumaViewProvider viewProvider = mock(VmNumaViewProvider.class); view = mock(VmNumaView.class); @@ -113,7 +111,7 @@ actionListener = ArgumentCaptor.forClass(ActionListener.class); doNothing().when(view).addActionListener(actionListener.capture()); - vmNumaController = new VmNumaController(appSvc, numaDAO, vmNumaDAO, vmId, agentId, viewProvider); + vmNumaController = new VmNumaController(appSvc, numaDAO, vmNumaDAO, vmRef, viewProvider); } private List<VmNumaStat> createStats() {
--- a/vm-numa/client-swing/src/main/java/com/redhat/thermostat/vm/numa/client/swing/internal/VmNumaPanel.java Thu Jun 09 08:58:57 2016 -0400 +++ b/vm-numa/client-swing/src/main/java/com/redhat/thermostat/vm/numa/client/swing/internal/VmNumaPanel.java Thu Jun 09 09:32:01 2016 -0400 @@ -59,13 +59,13 @@ import org.jfree.data.time.TimeSeries; import org.jfree.data.time.TimeSeriesCollection; +import com.redhat.thermostat.client.core.experimental.Duration; import com.redhat.thermostat.client.swing.SwingComponent; import com.redhat.thermostat.client.swing.components.HeaderPanel; import com.redhat.thermostat.client.swing.components.experimental.ThermostatChartPanel; import com.redhat.thermostat.client.swing.experimental.ComponentVisibilityNotifier; import com.redhat.thermostat.common.ActionListener; import com.redhat.thermostat.common.ActionNotifier; -import com.redhat.thermostat.common.Duration; import com.redhat.thermostat.shared.locale.Translate; import com.redhat.thermostat.storage.model.DiscreteTimeData; import com.redhat.thermostat.vm.numa.client.core.VmNumaView;
--- a/vm-numa/common/src/main/java/com/redhat/thermostat/vm/numa/common/VmNumaDAO.java Thu Jun 09 08:58:57 2016 -0400 +++ b/vm-numa/common/src/main/java/com/redhat/thermostat/vm/numa/common/VmNumaDAO.java Thu Jun 09 09:32:01 2016 -0400 @@ -40,26 +40,20 @@ import java.util.List; import com.redhat.thermostat.annotations.Service; -import com.redhat.thermostat.storage.core.AgentId; import com.redhat.thermostat.storage.core.Category; import com.redhat.thermostat.storage.core.Key; -import com.redhat.thermostat.storage.core.VmId; +import com.redhat.thermostat.storage.core.VmRef; @Service public interface VmNumaDAO { - static final Key<VmNumaNodeStat[]> vmNodeStats = new Key<>("vmNodeStats"); + Key<VmNumaNodeStat[]> vmNodeStats = new Key<>("vmNodeStats"); - static final Category<VmNumaStat> vmNumaStatCategory = new Category<>("vm-numa-stats", VmNumaStat.class, + Category<VmNumaStat> vmNumaStatCategory = new Category<>("vm-numa-stats", VmNumaStat.class, Arrays.<Key<?>>asList(Key.AGENT_ID, Key.VM_ID, Key.TIMESTAMP, vmNodeStats), Arrays.<Key<?>>asList(Key.TIMESTAMP)); void putVmNumaStat(VmNumaStat stat); - List<VmNumaStat> getNumaStats(AgentId agentId, VmId vmId, long since, long to); - - VmNumaStat getNewest(AgentId agentId, VmId vmId); - - VmNumaStat getOldest(AgentId agentId, VmId id); - + List<VmNumaStat> getNumaStats(VmRef vmRef, long since, long to); }
--- a/vm-numa/common/src/main/java/com/redhat/thermostat/vm/numa/common/internal/VmNumaDAOImpl.java Thu Jun 09 08:58:57 2016 -0400 +++ b/vm-numa/common/src/main/java/com/redhat/thermostat/vm/numa/common/internal/VmNumaDAOImpl.java Thu Jun 09 09:32:01 2016 -0400 @@ -37,24 +37,23 @@ package com.redhat.thermostat.vm.numa.common.internal; import java.util.List; +import java.util.logging.Level; import java.util.logging.Logger; import com.redhat.thermostat.common.utils.LoggingUtils; -import com.redhat.thermostat.storage.core.AgentId; -import com.redhat.thermostat.storage.core.HostRef; +import com.redhat.thermostat.storage.core.DescriptorParsingException; import com.redhat.thermostat.storage.core.Key; import com.redhat.thermostat.storage.core.PreparedStatement; +import com.redhat.thermostat.storage.core.StatementDescriptor; +import com.redhat.thermostat.storage.core.StatementExecutionException; import com.redhat.thermostat.storage.core.Storage; import com.redhat.thermostat.storage.core.VmBoundaryPojoGetter; -import com.redhat.thermostat.storage.core.VmId; import com.redhat.thermostat.storage.core.VmRef; import com.redhat.thermostat.storage.core.VmTimeIntervalPojoListGetter; -import com.redhat.thermostat.storage.dao.AbstractDao; -import com.redhat.thermostat.storage.dao.AbstractDaoStatement; import com.redhat.thermostat.vm.numa.common.VmNumaDAO; import com.redhat.thermostat.vm.numa.common.VmNumaStat; -public class VmNumaDAOImpl extends AbstractDao implements VmNumaDAO { +public class VmNumaDAOImpl implements VmNumaDAO { private static final Logger logger = LoggingUtils.getLogger(VmNumaDAOImpl.class); @@ -83,35 +82,24 @@ @Override public void putVmNumaStat(final VmNumaStat stat) { - executeStatement(new AbstractDaoStatement<VmNumaStat>(storage, vmNumaStatCategory, DESC_ADD_VM_NUMA_STAT) { - @Override - public PreparedStatement<VmNumaStat> customize(PreparedStatement<VmNumaStat> preparedStatement) { - preparedStatement.setString(0, stat.getAgentId()); - preparedStatement.setString(1, stat.getVmId()); - preparedStatement.setLong(2, stat.getTimeStamp()); - preparedStatement.setPojoList(3, stat.getVmNodeStats()); - return preparedStatement; - } - }); + StatementDescriptor<VmNumaStat> desc = new StatementDescriptor<>(vmNumaStatCategory, DESC_ADD_VM_NUMA_STAT); + PreparedStatement<VmNumaStat> prepared; + try { + prepared = storage.prepareStatement(desc); + prepared.setString(0, stat.getAgentId()); + prepared.setString(1, stat.getVmId()); + prepared.setLong(2, stat.getTimeStamp()); + prepared.setPojoList(3, stat.getVmNodeStats()); + prepared.execute(); + } catch (DescriptorParsingException e) { + logger.log(Level.SEVERE, "Preparing stmt '" + desc + "' failed!", e); + } catch (StatementExecutionException e) { + logger.log(Level.SEVERE, "Executing stmt '" + desc + "' failed!", e); + } } @Override - public List<VmNumaStat> getNumaStats(AgentId agentId, VmId vmId, long since, long to) { - return intervalGetter.getLatest(new VmRef(new HostRef(agentId.get(), ""), vmId.get(), -1, ""), since, to); - } - - @Override - public VmNumaStat getNewest(AgentId agentId, VmId vmId) { - return boundaryGetter.getOldestStat(new VmRef(new HostRef(agentId.get(), ""), "", -1, "")); - } - - @Override - public VmNumaStat getOldest(AgentId agentId, VmId id) { - return boundaryGetter.getOldestStat(new VmRef(new HostRef(agentId.get(), ""), "", -1, "")); - } - - @Override - protected Logger getLogger() { - return logger; + public List<VmNumaStat> getNumaStats(VmRef vmRef, long since, long to) { + return intervalGetter.getLatest(vmRef, since, to); } }
--- a/vm-numa/common/src/main/java/com/redhat/thermostat/vm/numa/common/internal/VmNumaDAOImplStatementDescriptorRegistration.java Thu Jun 09 08:58:57 2016 -0400 +++ b/vm-numa/common/src/main/java/com/redhat/thermostat/vm/numa/common/internal/VmNumaDAOImplStatementDescriptorRegistration.java Thu Jun 09 09:32:01 2016 -0400 @@ -39,9 +39,11 @@ import java.util.HashSet; import java.util.Set; +import com.redhat.thermostat.storage.core.PreparedParameter; import com.redhat.thermostat.storage.core.VmBoundaryPojoGetter; import com.redhat.thermostat.storage.core.VmLatestPojoListGetter; import com.redhat.thermostat.storage.core.VmTimeIntervalPojoListGetter; +import com.redhat.thermostat.storage.core.auth.DescriptorMetadata; import com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration; import com.redhat.thermostat.vm.numa.common.VmNumaDAO; @@ -66,4 +68,9 @@ descs.add(rangeDescriptor); return descs; } + + @Override + public DescriptorMetadata getDescriptorMetadata(String descriptor, PreparedParameter[] params) { + throw new AssertionError("Should not be used"); + } }