Mercurial > hg > release > thermostat-1.6
changeset 1908:cb6390cf824b
Add vm-numa plugin base to Thermostat.
This is a backport of the vm-numa plugin from the hg/thermostat repository
revision fd3632b6449c. This changeset does 'not' compile and relies on
the commit ahead: "Complete vm-numa plugin" which includes the changes to
work with this repository. This commit 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
--- a/distribution/assembly/all-plugin-assembly.xml Tue Jun 07 11:55:47 2016 -0400 +++ b/distribution/assembly/all-plugin-assembly.xml Thu Jun 09 08:58:57 2016 -0400 @@ -70,6 +70,7 @@ <include>com.redhat.thermostat:thermostat-schema-info-distribution</include> <include>com.redhat.thermostat:thermostat-web-endpoint-distribution</include> <include>com.redhat.thermostat:thermostat-killvm-distribution</include> + <include>com.redhat.thermostat:thermostat-vm-numa-distribution</include> </includes> </dependencySet> </dependencySets>
--- a/distribution/packaging/fedora/thermostat.spec Tue Jun 07 11:55:47 2016 -0400 +++ b/distribution/packaging/fedora/thermostat.spec Thu Jun 09 08:58:57 2016 -0400 @@ -1045,6 +1045,7 @@ %{_datadir}/%{pkg_name}/plugins/vm-heap-analysis %{_datadir}/%{pkg_name}/plugins/vm-jmx %{_datadir}/%{pkg_name}/plugins/vm-memory +%{_datadir}/%{pkg_name}/plugins/vm-numa %{_datadir}/%{pkg_name}/plugins/vm-overview %{_datadir}/%{pkg_name}/plugins/vm-profiler %{_datadir}/%{pkg_name}/cache
--- a/distribution/pom.xml Tue Jun 07 11:55:47 2016 -0400 +++ b/distribution/pom.xml Thu Jun 09 08:58:57 2016 -0400 @@ -560,6 +560,12 @@ <version>${project.version}</version> <type>zip</type> </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-vm-numa-distribution</artifactId> + <version>${project.version}</version> + <type>zip</type> + </dependency> <!-- list-categories command --> <dependency>
--- a/pom.xml Tue Jun 07 11:55:47 2016 -0400 +++ b/pom.xml Thu Jun 09 08:58:57 2016 -0400 @@ -243,6 +243,7 @@ <module>vm-profiler</module> <module>notes</module> <module>numa</module> + <module>vm-numa</module> <module>laf-utils</module> <module>thermostat-plugin-validator</module> <module>validate-command</module>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/agent/pom.xml Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,104 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + 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. + +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>thermostat-vm-numa</artifactId> + <groupId>com.redhat.thermostat</groupId> + <version>1.5.8-SNAPSHOT</version> + </parent> + <artifactId>thermostat-vm-numa-agent</artifactId> + <packaging>bundle</packaging> + <name>Thermostat VM NUMA Agent plugin</name> + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Bundle-Vendor>Red Hat, Inc.</Bundle-Vendor> + <Bundle-SymbolicName>com.redhat.thermostat.vm.numa.agent</Bundle-SymbolicName> + <Bundle-Activator>com.redhat.thermostat.vm.numa.agent.internal.Activator</Bundle-Activator> + <Export-Package /> + <Private-Package> + com.redhat.thermostat.vm.numa.agent.internal + </Private-Package> + <!-- Do not autogenerate uses clauses in Manifests --> + <_nouses>true</_nouses> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-common-test</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.core</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-agent-core</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-vm-numa-common</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> +</project>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/agent/src/main/java/com/redhat/thermostat/vm/numa/agent/internal/Activator.java Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,113 @@ +/* + * 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.vm.numa.agent.internal; + +import java.util.Map; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceRegistration; + +import com.redhat.thermostat.agent.VmStatusListenerRegistrar; +import com.redhat.thermostat.backend.Backend; +import com.redhat.thermostat.backend.BackendService; +import com.redhat.thermostat.common.MultipleServiceTracker; +import com.redhat.thermostat.common.Version; +import com.redhat.thermostat.storage.core.WriterID; +import com.redhat.thermostat.vm.numa.common.VmNumaDAO; + +public class Activator implements BundleActivator { + + private ScheduledExecutorService executor; + private MultipleServiceTracker tracker; + private VmNumaBackend backend; + private ServiceRegistration<Backend> reg; + + @Override + public void start(final BundleContext context) throws Exception { + final VmStatusListenerRegistrar registrar = new VmStatusListenerRegistrar(context); + executor = Executors.newSingleThreadScheduledExecutor(); + Class<?>[] deps = new Class<?>[] { + BackendService.class, + VmNumaDAO.class, + WriterID.class, + }; + + tracker = new MultipleServiceTracker(context, deps, new MultipleServiceTracker.Action() { + @Override + public void dependenciesAvailable(Map<String, Object> services) { + VmNumaDAO vmNumaDAO = (VmNumaDAO) services.get(VmNumaDAO.class.getName()); + Version version = new Version(context.getBundle()); + WriterID writerID = (WriterID) services.get(WriterID.class.getName()); + backend = constructBackend(executor, vmNumaDAO, version, registrar, writerID); + if (backend.canRegister()) { + reg = context.registerService(Backend.class, backend, null); + } + } + + @Override + public void dependenciesUnavailable() { + if (backend.isActive()) { + backend.deactivate(); + } + if (reg != null) { + reg.unregister(); + } + } + }); + + tracker.open(); + + } + + @Override + public void stop(BundleContext context) throws Exception { + tracker.close(); + } + + //Package private for testing + VmNumaBackend getBackend() { + return backend; + } + + //Package private for testing + VmNumaBackend constructBackend(ScheduledExecutorService executor, VmNumaDAO vmNumaDAO, Version version, VmStatusListenerRegistrar registrar, WriterID writerID) { + return new VmNumaBackend(executor, vmNumaDAO, version, registrar, writerID); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/agent/src/main/java/com/redhat/thermostat/vm/numa/agent/internal/VmNumaBackend.java Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,122 @@ +/* + * 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.vm.numa.agent.internal; + +import java.io.IOException; +import java.text.ParseException; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ScheduledExecutorService; +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.redhat.thermostat.agent.VmStatusListenerRegistrar; +import com.redhat.thermostat.backend.VmPollingAction; +import com.redhat.thermostat.backend.VmPollingBackend; +import com.redhat.thermostat.common.Version; +import com.redhat.thermostat.common.utils.LoggingUtils; +import com.redhat.thermostat.storage.core.WriterID; +import com.redhat.thermostat.vm.numa.common.VmNumaDAO; +import com.redhat.thermostat.vm.numa.common.VmNumaStat; + +public class VmNumaBackend extends VmPollingBackend { + + private final VmNumaBackendAction action; + private static final Logger logger = LoggingUtils.getLogger(VmNumaBackend.class); + + public VmNumaBackend(ScheduledExecutorService executor, VmNumaDAO vmNumaDAO, Version version, + VmStatusListenerRegistrar registrar, WriterID id) { + super("VM NUMA Backend", + "Gathers NUMA statistics about a vm", + "Red Hat, Inc.", + version, executor, registrar); + this.action = new VmNumaBackendAction(id, vmNumaDAO); + registerAction(action); + } + + @Override + public int getOrderValue() { + return ORDER_MEMORY_GROUP; + } + + private static class VmNumaBackendAction implements VmPollingAction { + private VmNumaDAO dao; + private WriterID writerID; + private Map<Integer, VmNumaCollector> collectors; + + private VmNumaBackendAction(final WriterID writerID, VmNumaDAO dao) { + this.writerID = writerID; + this.dao = dao; + this.collectors = new HashMap<>(); + } + + @Override + public void run(String vmId, int pid) { + if (!collectors.containsKey(pid)) { + collectors.put(pid, new VmNumaCollector(pid)); + } + + try { + VmNumaStat data = collectors.get(pid).collect(); + data.setAgentId(writerID.getWriterID()); + data.setVmId(vmId); + dao.putVmNumaStat(data); + } catch (ParseException e) { + logger.log(Level.WARNING, "Unable to add numastat data for vm: " + vmId); + } + } + } + + /** + * VmNumaBackend requires numastat process to function + * @return true if numastat process exists, false otherwise + */ + public boolean canRegister() { + try { + Runtime.getRuntime().exec("numastat"); + return true; + } catch (IOException e) { + //numastat does not exist, do nothing + } + return false; + } + + // For testing purposes only + void setVmNumaBackendCollector(int pid, VmNumaCollector collector) { + action.collectors.put(pid, collector); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/agent/src/main/java/com/redhat/thermostat/vm/numa/agent/internal/VmNumaCollector.java Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,85 @@ +/* + * 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.vm.numa.agent.internal; + +import java.io.IOException; +import java.io.InputStream; +import java.text.ParseException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.redhat.thermostat.common.utils.LoggingUtils; +import com.redhat.thermostat.common.utils.StreamUtils; +import com.redhat.thermostat.vm.numa.common.VmNumaStat; + +public class VmNumaCollector { + + private static final String PROCESS = "numastat"; + private static final Logger logger = LoggingUtils.getLogger(VmNumaCollector.class); + + private final ProcessBuilder processBuilder; + private final VmNumaStatParser parser; + + public VmNumaCollector(int pid) { + this.processBuilder = new ProcessBuilder(PROCESS, String.valueOf(pid)); + this.parser = new VmNumaStatParser(); + } + + public VmNumaStat collect() throws ParseException { + String output = getOutput(); + return parser.parse(output); + } + + private String getOutput() { + try { + Process p = startProcess(); + + InputStream is = p.getInputStream(); + return new String(StreamUtils.readAll(is)); + } catch (InterruptedException | IOException e) { + logger.log(Level.WARNING, "Unable to run process numastat"); + } + return ""; + } + + //For testing + Process startProcess() throws InterruptedException, IOException { + Process p = processBuilder.start(); + p.waitFor(); + return p; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/agent/src/main/java/com/redhat/thermostat/vm/numa/agent/internal/VmNumaStatParser.java Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,86 @@ +/* + * 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.vm.numa.agent.internal; + +import java.text.ParseException; + +import com.redhat.thermostat.vm.numa.common.VmNumaNodeStat; +import com.redhat.thermostat.vm.numa.common.VmNumaStat; + +public class VmNumaStatParser { + public VmNumaStat parse(String input) throws ParseException { + VmNumaStat stat = new VmNumaStat(); + stat.setTimeStamp(System.currentTimeMillis()); + String[] lines = input.split(System.lineSeparator()); + try { + VmNumaNodeStat[] stats = parseStats(lines[4], lines[5], lines[6], lines[7]); + stat.setVmNodeStats(stats); + return stat; + } catch (NumberFormatException | ArrayIndexOutOfBoundsException | NegativeArraySizeException e) { + throw new ParseException("Unexpected input to VmNumaStatParser", 0); + } + } + + private VmNumaNodeStat[] parseStats(String HUGE, String HEAP, String STACK, String PRIVATE) { + VmNumaNodeStat[] stats; + + String[] hugeStats = splitWhitespaces(HUGE); + String[] heapStats = splitWhitespaces(HEAP); + String[] stackStats = splitWhitespaces(STACK); + String[] privateStats = splitWhitespaces(PRIVATE); + + //Take the maximum in-case of erroneous input + int numberOfNodes = -2 + Math.max(hugeStats.length, + Math.max(heapStats.length, + Math.max(stackStats.length, privateStats.length))); + + stats = new VmNumaNodeStat[numberOfNodes]; + for (int i = 0; i < numberOfNodes; i++) { + stats[i] = new VmNumaNodeStat(); + stats[i].setNode(i); + stats[i].setHugeMemory(Double.parseDouble(hugeStats[i + 1])); + stats[i].setHeapMemory(Double.parseDouble(heapStats[i + 1])); + stats[i].setStackMemory(Double.parseDouble(stackStats[i + 1])); + stats[i].setPrivateMemory(Double.parseDouble(privateStats[i + 1])); + } + return stats; + } + + private String[] splitWhitespaces(String s) { + return s.split("\\s+"); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/agent/src/test/java/com/redhat/thermostat/vm/numa/agent/internal/ActivatorTest.java Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,125 @@ +/* + * 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.vm.numa.agent.internal; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.concurrent.ScheduledExecutorService; + +import org.junit.Ignore; +import org.junit.Test; +import org.osgi.framework.Bundle; +import org.osgi.framework.Version; + +import com.redhat.thermostat.agent.VmStatusListenerRegistrar; +import com.redhat.thermostat.backend.Backend; +import com.redhat.thermostat.backend.BackendService; +import com.redhat.thermostat.storage.core.WriterID; +import com.redhat.thermostat.testutils.StubBundleContext; +import com.redhat.thermostat.vm.numa.common.VmNumaDAO; + +public class ActivatorTest { + @Test + public void verifyActivatorDoesNotRegisterServiceOnMissingDeps() throws Exception { + StubBundleContext context = new StubBundleContext(); + + Activator activator = new Activator(); + + activator.start(context); + + assertEquals(0, context.getAllServices().size()); + assertEquals(3, context.getServiceListeners().size()); + + activator.stop(context); + } + + @Test + public void verifyActivatorRegistersServices() throws Exception { + StubBundleContext context = new StubBundleContext() { + @Override + public Bundle getBundle() { + Bundle result = mock(Bundle.class); + when(result.getVersion()).thenReturn(Version.emptyVersion); + return result; + } + }; + BackendService service = mock(BackendService.class); + VmNumaDAO vmNumaDAO = mock(VmNumaDAO.class); + WriterID idService = mock(WriterID.class); + + context.registerService(BackendService.class.getName(), service, null); + context.registerService(VmNumaDAO.class, vmNumaDAO, null); + context.registerService(WriterID.class, idService, null); + + final VmNumaBackend[] mock = new VmNumaBackend[1]; + + Activator activator = new Activator() { + @Override + VmNumaBackend constructBackend(ScheduledExecutorService executor, VmNumaDAO vmNumaDAO, com.redhat.thermostat.common.Version version, VmStatusListenerRegistrar registrar, WriterID writerID) { + mock[0] = new VmNumaBackend(executor, vmNumaDAO, version, registrar, writerID) + { + @Override + public boolean canRegister() { + return true; + } + }; + return mock[0]; + } + }; + + activator.start(context); + + assertTrue(context.isServiceRegistered(Backend.class.getName(), mock[0].getClass())); + VmNumaBackend backend = activator.getBackend(); + assertNotNull(backend); + + // core thermostat will activate the backend once it's registered + backend.activate(); + + activator.stop(context); + + assertFalse(backend.isActive()); + + assertEquals(0, context.getServiceListeners().size()); + assertEquals(3, context.getAllServices().size()); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/agent/src/test/java/com/redhat/thermostat/vm/numa/agent/internal/VmNumaBackendTest.java Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,167 @@ +/* + * 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.vm.numa.agent.internal; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Matchers.isA; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; + +import java.text.ParseException; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; + +import com.redhat.thermostat.agent.VmStatusListener; +import com.redhat.thermostat.agent.VmStatusListenerRegistrar; +import com.redhat.thermostat.common.Ordered; +import com.redhat.thermostat.common.Version; +import com.redhat.thermostat.storage.core.WriterID; +import com.redhat.thermostat.vm.numa.common.VmNumaDAO; +import com.redhat.thermostat.vm.numa.common.VmNumaStat; + +public class VmNumaBackendTest { + private VmNumaBackend backend; + private VmNumaDAO vmNumaDAO; + private ScheduledExecutorService executor; + private VmStatusListenerRegistrar registrar; + + @Before + public void setup() { + executor = mock(ScheduledExecutorService.class); + vmNumaDAO = mock(VmNumaDAO.class); + + Version version = mock(Version.class); + when(version.getVersionNumber()).thenReturn("0.0.0"); + + registrar = mock(VmStatusListenerRegistrar.class); + + WriterID id = mock(WriterID.class); + when(id.getWriterID()).thenReturn("id"); + backend = new VmNumaBackend(executor, vmNumaDAO, version, registrar, id); + } + + @Test + public void testActivate() { + backend.activate(); + + verify(executor).scheduleAtFixedRate(isA(Runnable.class), eq(0l), eq(1000l), eq(TimeUnit.MILLISECONDS)); + verify(registrar).register(backend); + assertTrue(backend.isActive()); + } + + @Test + public void testActivateTwice() { + assertTrue(backend.activate()); + assertTrue(backend.isActive()); + assertTrue(backend.activate()); + assertTrue(backend.isActive()); + + assertTrue(backend.deactivate()); + } + + @Test + public void testDeactivate() { + backend.activate(); + backend.deactivate(); + + verify(executor).shutdown(); + verify(registrar).unregister(backend); + assertFalse(backend.isActive()); + } + + + @Test + public void testDeactivateTwice() { + assertTrue(backend.activate()); + assertTrue(backend.isActive()); + + assertTrue(backend.deactivate()); + assertFalse(backend.isActive()); + assertTrue(backend.deactivate()); + assertFalse(backend.isActive()); + } + + @Test + public void testStart() throws ParseException { + mockCollector(backend, 0); + mockCollector(backend, 1); + + backend.activate(); + + verify(registrar).register(backend); + ArgumentCaptor<Runnable> captor = ArgumentCaptor.forClass(Runnable.class); + verify(executor).scheduleAtFixedRate(captor.capture(), any(Long.class), any(Long.class), any(TimeUnit.class)); + assertTrue(backend.isActive()); + + backend.vmStatusChanged(VmStatusListener.Status.VM_ACTIVE, "vm1", 0); + backend.vmStatusChanged(VmStatusListener.Status.VM_STARTED, "vm2", 1); + + Runnable runnable = captor.getValue(); + runnable.run(); + + verify(vmNumaDAO, times(2)).putVmNumaStat(any(VmNumaStat.class)); + + backend.vmStatusChanged(VmStatusListener.Status.VM_STOPPED, "vm1", 0); + backend.vmStatusChanged(VmStatusListener.Status.VM_STOPPED, "vm2", 1); + + runnable.run(); + verifyNoMoreInteractions(vmNumaDAO); + } + + private void mockCollector(VmNumaBackend backend, int pid) throws ParseException { + VmNumaCollector collector = mock(VmNumaCollector.class); + when(collector.collect()).thenReturn(mock(VmNumaStat.class)); + backend.setVmNumaBackendCollector(pid, collector); + } + + @Test + public void testOrderValue() { + int orderValue = backend.getOrderValue(); + + assertTrue(orderValue == Ordered.ORDER_MEMORY_GROUP); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/agent/src/test/java/com/redhat/thermostat/vm/numa/agent/internal/VmNumaCollectorTest.java Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,156 @@ +/* + * 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.vm.numa.agent.internal; + +import static org.junit.Assert.assertTrue; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.text.ParseException; + +import org.junit.Ignore; +import org.junit.Test; + +import com.redhat.thermostat.vm.numa.common.VmNumaNodeStat; +import com.redhat.thermostat.vm.numa.common.VmNumaStat; + +public class VmNumaCollectorTest { + + private VmNumaCollector collector; + + @Test + public void testCollectSingleNodeStat() throws ParseException { + final String input = "\n" + + "Per-node process memory usage (in MBs) for PID 16816 (java)\n" + + " Node 0 Total\n" + + " --------------- ---------------\n" + + "Huge 0.00 0.00\n" + + "Heap 0.05 0.05\n" + + "Stack 6.27 6.27\n" + + "Private 385.07 385.07\n" + + "---------------- --------------- ---------------\n" + + "Total 391.39 391.39"; + setupCollector(input); + + VmNumaStat stat = collector.collect(); + VmNumaNodeStat[] stats = stat.getVmNodeStats(); + assertTrue(stats.length == 1); + VmNumaNodeStat nodeStat = stats[0]; + assertTrue(nodeStat.getNode() == 0); + assertTrue(nodeStat.getHugeMemory() == 0); + assertTrue(nodeStat.getHeapMemory() == 0.05d); + assertTrue(nodeStat.getStackMemory() == 6.27d); + assertTrue(nodeStat.getPrivateMemory() == 385.07d); + } + + @Test + public void testCollectMultipleNodeStat() throws ParseException { + final String input = "\n" + + "Per-node process memory usage (in MBs) for PID 3 (ksoftirqd/0)\n" + + " Node 0 Node 1 Total\n" + + " --------------- --------------- ---------------\n" + + "Huge 0.00 0.00 0.00\n" + + "Heap 0.00 0.00 0.00\n" + + "Stack 4.00 1.00 5.00\n" + + "Private 5.00 2.00 7.00\n" + + "---------------- --------------- --------------- ---------------\n" + + "Total 9.00 3.00 12.00"; + + setupCollector(input); + + VmNumaStat stat = collector.collect(); + VmNumaNodeStat[] stats = stat.getVmNodeStats(); + + assertTrue(stats.length == 2); + + VmNumaNodeStat nodeStat1 = stats[0]; + assertTrue(nodeStat1.getNode() == 0); + assertTrue(nodeStat1.getHugeMemory() == 0d); + assertTrue(nodeStat1.getHeapMemory() == 0d); + assertTrue(nodeStat1.getStackMemory() == 4d); + assertTrue(nodeStat1.getPrivateMemory() == 5d); + + VmNumaNodeStat nodeStat2 = stats[1]; + assertTrue(nodeStat2.getNode() == 1); + assertTrue(nodeStat2.getHugeMemory() == 0d); + assertTrue(nodeStat2.getHeapMemory() == 0d); + assertTrue(nodeStat2.getStackMemory() == 1d); + assertTrue(nodeStat2.getPrivateMemory() == 2d); + } + + private void setupCollector(final String input) { + collector = new VmNumaCollector(0) { + @Override + protected Process startProcess() { + return new Process() { + @Override + public OutputStream getOutputStream() { + return null; + } + + @Override + public InputStream getInputStream() { + return new ByteArrayInputStream(input.getBytes()); + } + + @Override + public InputStream getErrorStream() { + return null; + } + + @Override + public int waitFor() throws InterruptedException { + return 0; + } + + @Override + public int exitValue() { + return 0; + } + + @Override + public void destroy() { + //Do nothing + } + }; + } + }; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/agent/src/test/java/com/redhat/thermostat/vm/numa/agent/internal/VmNumaStatParserTest.java Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,147 @@ +/* + * 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.vm.numa.agent.internal; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.text.ParseException; + +import org.junit.Test; + +import com.redhat.thermostat.vm.numa.common.VmNumaNodeStat; +import com.redhat.thermostat.vm.numa.common.VmNumaStat; + +public class VmNumaStatParserTest { + + private final VmNumaStatParser parser = new VmNumaStatParser(); + + @Test + public void testParseSingleNodeStat() throws ParseException { + final String input = "\n" + + "Per-node process memory usage (in MBs) for PID 16816 (java)\n" + + " Node 0 Total\n" + + " --------------- ---------------\n" + + "Huge 0.00 0.00\n" + + "Heap 0.05 0.05\n" + + "Stack 6.27 6.27\n" + + "Private 385.07 385.07\n" + + "---------------- --------------- ---------------\n" + + "Total 391.39 391.39"; + + VmNumaStat stat = parser.parse(input); + VmNumaNodeStat[] stats = stat.getVmNodeStats(); + assertTrue(stats.length == 1); + VmNumaNodeStat nodeStat = stats[0]; + assertTrue(nodeStat.getNode() == 0); + assertTrue(nodeStat.getHugeMemory() == 0); + assertTrue(nodeStat.getHeapMemory() == 0.05d); + assertTrue(nodeStat.getStackMemory() == 6.27d); + assertTrue(nodeStat.getPrivateMemory() == 385.07d); + } + + @Test + public void testParseMultipleNodeStat() throws ParseException { + final String input = "\n" + + "Per-node process memory usage (in MBs) for PID 3 (ksoftirqd/0)\n" + + " Node 0 Node 1 Total\n" + + " --------------- --------------- ---------------\n" + + "Huge 0.00 0.00 0.00\n" + + "Heap 0.00 0.00 0.00\n" + + "Stack 4.00 1.00 5.00\n" + + "Private 5.00 2.00 7.00\n" + + "---------------- --------------- --------------- ---------------\n" + + "Total 9.00 3.00 12.00"; + + VmNumaStat stat = parser.parse(input); + VmNumaNodeStat[] stats = stat.getVmNodeStats(); + + assertTrue(stats.length == 2); + + VmNumaNodeStat nodeStat1 = stats[0]; + assertTrue(nodeStat1.getNode() == 0); + assertTrue(nodeStat1.getHugeMemory() == 0d); + assertTrue(nodeStat1.getHeapMemory() == 0d); + assertTrue(nodeStat1.getStackMemory() == 4d); + assertTrue(nodeStat1.getPrivateMemory() == 5d); + + VmNumaNodeStat nodeStat2 = stats[1]; + assertTrue(nodeStat2.getNode() == 1); + assertTrue(nodeStat2.getHugeMemory() == 0d); + assertTrue(nodeStat2.getHeapMemory() == 0d); + assertTrue(nodeStat2.getStackMemory() == 1d); + assertTrue(nodeStat2.getPrivateMemory() == 2d); + } + + @Test (expected = ParseException.class) + public void testParseEmptyString() throws ParseException { + String input = ""; + VmNumaStat stat = parser.parse(input); + } + + @Test (expected = ParseException.class) + public void testParseIncorrectMemoryData() throws ParseException { + final String input = "\n" + + "Per-node process memory usage (in MBs) for PID 3 (ksoftirqd/0)\n" + + " Node 0 Node 1 Total\n" + + " --------------- --------------- ---------------\n" + + "Huge ABCD 0.00 0.00\n" + + "Heap 0.00 0.00 0.00\n" + + "Stack 4.00 1.00 5.00\n" + + "Private 5.00 2.00 7.00\n" + + "---------------- --------------- --------------- ---------------\n" + + "Total 9.00 3.00 12.00"; + + parser.parse(input); + } + + @Test (expected = ParseException.class) + public void testParseIncorrectMemory() throws ParseException { + final String input = "\n" + + "Per-node process memory usage (in MBs) for PID 3 (ksoftirqd/0)\n" + + " Node 0 Node 1 Total\n" + + " --------------- --------------- ---------------\n" + + "Huge\n" + + "Heap 0.00 0.00 0.00\n" + + "Stack 4.00 1.00 5.00\n" + + "Private 5.00 2.00 7.00\n" + + "---------------- --------------- --------------- ---------------\n" + + "Total 9.00 3.00 12.00"; + + parser.parse(input); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/client-core/pom.xml Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,122 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + 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. + +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>thermostat-vm-numa</artifactId> + <groupId>com.redhat.thermostat</groupId> + <version>1.5.8-SNAPSHOT</version> + </parent> + <artifactId>thermostat-vm-numa-client-core</artifactId> + <packaging>bundle</packaging> + <name>Thermostat VM NUMA Core Client plugin</name> + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Bundle-Vendor>Red Hat, Inc.</Bundle-Vendor> + <Bundle-SymbolicName>com.redhat.thermostat.vm.numa.client.core</Bundle-SymbolicName> + <Bundle-Activator>com.redhat.thermostat.vm.numa.client.core.internal.Activator</Bundle-Activator> + <Export-Package> + com.redhat.thermostat.vm.numa.client.core, + com.redhat.thermostat.vm.numa.client.core.locale + </Export-Package> + <Private-Package> + com.redhat.thermostat.vm.numa.client.core.internal + </Private-Package> + <!-- Do not autogenerate uses clauses in Manifests --> + <_nouses>true</_nouses> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-common-test</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.core</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-common-core</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-client-core</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-numa-common</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-vm-numa-common</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-storage-core</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> +</project>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/client-core/src/main/java/com/redhat/thermostat/vm/numa/client/core/VmNumaService.java Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,44 @@ +/* + * 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.vm.numa.client.core; + +import com.redhat.thermostat.client.core.InformationService; +import com.redhat.thermostat.storage.core.VmRef; + +public interface VmNumaService extends InformationService<VmRef> { + public static final String SERVICE_ID = "com.redhat.thermostat.vm.numa"; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/client-core/src/main/java/com/redhat/thermostat/vm/numa/client/core/VmNumaServiceImpl.java Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,83 @@ +/* + * 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.vm.numa.client.core; + +import com.redhat.thermostat.client.core.NameMatchingRefFilter; +import com.redhat.thermostat.client.core.controllers.InformationServiceController; +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; + +public class VmNumaServiceImpl implements VmNumaService { + + private static final int ORDER = ORDER_MEMORY_GROUP; + private static final Filter<VmRef> FILTER = new NameMatchingRefFilter<>(); + + private ApplicationService appSvc; + private VmNumaDAO vmNumaDAO; + private VmNumaViewProvider vmNumaViewProvider; + private NumaDAO numaDAO; + + public VmNumaServiceImpl(ApplicationService applicationService, NumaDAO numaDAO, VmNumaDAO vmNumaDAO, VmNumaViewProvider vmNumaViewProvider) { + this.appSvc = applicationService; + this.vmNumaDAO = vmNumaDAO; + this.vmNumaViewProvider = vmNumaViewProvider; + this.numaDAO = numaDAO; + } + + @Override + public Filter<VmRef> getFilter() { + return FILTER; + } + + @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); + } + + @Override + public int getOrderValue() { + return ORDER; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/client-core/src/main/java/com/redhat/thermostat/vm/numa/client/core/VmNumaView.java Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,67 @@ +/* + * 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.vm.numa.client.core; + +import java.util.concurrent.TimeUnit; + +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 { + + public enum UserAction { + USER_CHANGED_TIME_RANGE; + } + + public abstract void addUserActionListener(ActionListener<UserAction> listener); + + public abstract void removeUserActionListener(ActionListener<UserAction> listener); + + public abstract Duration getUserDesiredDuration(); + + public abstract void setVisibleDataRange(Duration duration); + + public abstract void addData(String seriesName, int nodeNumber, DiscreteTimeData<Double> data); + + public abstract void addChart(int numNumaNodes, String name); + + public abstract void showNumaUnavailable(); + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/client-core/src/main/java/com/redhat/thermostat/vm/numa/client/core/VmNumaViewProvider.java Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,44 @@ +/* + * 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.vm.numa.client.core; + +import com.redhat.thermostat.client.core.views.ViewProvider; + +public interface VmNumaViewProvider extends ViewProvider { + @Override + public VmNumaView createView(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/client-core/src/main/java/com/redhat/thermostat/vm/numa/client/core/internal/Activator.java Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,100 @@ +/* + * 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.vm.numa.client.core.internal; + +import java.util.Dictionary; +import java.util.Hashtable; +import java.util.Map; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceRegistration; + +import com.redhat.thermostat.client.core.InformationService; +import com.redhat.thermostat.common.ApplicationService; +import com.redhat.thermostat.common.Constants; +import com.redhat.thermostat.common.MultipleServiceTracker; +import com.redhat.thermostat.numa.common.NumaDAO; +import com.redhat.thermostat.storage.core.VmRef; +import com.redhat.thermostat.vm.numa.client.core.VmNumaService; +import com.redhat.thermostat.vm.numa.client.core.VmNumaServiceImpl; +import com.redhat.thermostat.vm.numa.client.core.VmNumaViewProvider; +import com.redhat.thermostat.vm.numa.common.VmNumaDAO; + +public class Activator implements BundleActivator { + + private MultipleServiceTracker tracker; + private ServiceRegistration reg; + + @Override + public void start(final BundleContext context) throws Exception { + Class<?>[] deps = new Class<?>[] { + VmNumaDAO.class, + ApplicationService.class, + VmNumaViewProvider.class, + NumaDAO.class, + }; + + tracker = new MultipleServiceTracker(context, deps, new MultipleServiceTracker.Action() { + @Override + public void dependenciesAvailable(Map<String, Object> services) { + VmNumaDAO vmNumaDAO = (VmNumaDAO) services.get(VmNumaDAO.class.getName()); + ApplicationService applicationService = (ApplicationService) services.get(ApplicationService.class.getName()); + VmNumaViewProvider vmNumaViewProvider = (VmNumaViewProvider) services.get(VmNumaViewProvider.class.getName()); + NumaDAO numaDAO = (NumaDAO) services.get(NumaDAO.class.getName()); + + VmNumaServiceImpl vmNumaService = new VmNumaServiceImpl(applicationService, numaDAO, vmNumaDAO, vmNumaViewProvider); + Dictionary<String, String> properties = new Hashtable<>(); + properties.put(Constants.GENERIC_SERVICE_CLASSNAME, VmRef.class.getName()); + properties.put(InformationService.KEY_SERVICE_ID, VmNumaService.SERVICE_ID); + reg = context.registerService(InformationService.class.getName(), vmNumaService, properties); + } + + @Override + public void dependenciesUnavailable() { + reg.unregister(); + } + }); + + tracker.open(); + } + + @Override + public void stop(BundleContext context) throws Exception { + tracker.close(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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 @@ -0,0 +1,179 @@ +/* + * 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.vm.numa.client.core.internal; + +import java.util.List; +import java.util.concurrent.TimeUnit; + +import com.redhat.thermostat.client.core.controllers.InformationServiceController; +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; +import com.redhat.thermostat.vm.numa.client.core.VmNumaViewProvider; +import com.redhat.thermostat.vm.numa.client.core.locale.LocaleResources; +import com.redhat.thermostat.vm.numa.common.NumaMemoryLocations; +import com.redhat.thermostat.vm.numa.common.VmNumaDAO; +import com.redhat.thermostat.vm.numa.common.VmNumaNodeStat; +import com.redhat.thermostat.vm.numa.common.VmNumaStat; + +public class VmNumaController implements InformationServiceController<VmRef> { + + private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer(); + + private VmNumaView view; + + private VmId vmId; + private AgentId agentId; + 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; + + this.vmNumaDAO = vmNumaDAO; + + int numNumaNodes = numaDAO.getNumberOfNumaNodes(new HostRef(agentId.get(), "")); + + this.view = vmNumaViewProvider.createView(); + + if (numNumaNodes > 1) { + for (NumaMemoryLocations location : NumaMemoryLocations.values()) { + view.addChart(numNumaNodes, location.getName()); + } + + setupTimer(appSvc.getTimerFactory().createTimer()); + + view.addUserActionListener(new ActionListener<VmNumaView.UserAction>() { + @Override + public void actionPerformed(ActionEvent<VmNumaView.UserAction> actionEvent) { + switch (actionEvent.getActionId()) { + case USER_CHANGED_TIME_RANGE: + Duration duration = view.getUserDesiredDuration(); + lastSeenTimestamp = System.currentTimeMillis() - duration.asMilliseconds(); + view.setVisibleDataRange(duration); + break; + default: + throw new AssertionError("Unhandled action type: " + actionEvent.getActionId()); + } + } + }); + } else { + view.showNumaUnavailable(); + } + } + + private void setupTimer(final Timer timer) { + timer.setSchedulingType(Timer.SchedulingType.FIXED_RATE); + timer.setTimeUnit(TimeUnit.SECONDS); + timer.setInitialDelay(0); + timer.setDelay(5); + + timer.setAction(new Runnable() { + @Override + public void run() { + updateData(); + } + }); + + view.addActionListener(new com.redhat.thermostat.common.ActionListener<VmNumaView.Action>() { + @Override + public void actionPerformed(com.redhat.thermostat.common.ActionEvent<BasicView.Action> actionEvent) { + switch (actionEvent.getActionId()) { + case HIDDEN: + timer.stop(); + break; + case VISIBLE: + timer.start(); + break; + default: + throw new AssertionError("Unhandled action type"); + } + } + }); + } + + private void updateData() { + List<VmNumaStat> stats = vmNumaDAO.getNumaStats(agentId, vmId, lastSeenTimestamp, System.currentTimeMillis()); + + if (stats.size() > 0) { + lastSeenTimestamp = stats.get(stats.size() - 1).getTimeStamp(); + } + + for(VmNumaStat stat : stats) { + VmNumaNodeStat[] nodeStats = stat.getVmNodeStats(); + for (VmNumaNodeStat nodeStat : nodeStats) { + int node = nodeStat.getNode(); + long timestamp = stat.getTimeStamp(); + view.addData(NumaMemoryLocations.HEAP.getName(), node, + new DiscreteTimeData<>(timestamp, nodeStat.getHeapMemory())); + view.addData(NumaMemoryLocations.HUGE.getName(), node, + new DiscreteTimeData<>(timestamp, nodeStat.getHugeMemory())); + view.addData(NumaMemoryLocations.PRIVATE.getName(), node, + new DiscreteTimeData<>(timestamp, nodeStat.getPrivateMemory())); + view.addData(NumaMemoryLocations.STACK.getName(), node, + new DiscreteTimeData<>(timestamp, nodeStat.getStackMemory())); + } + } + } + + @Override + public UIComponent getView() { + return view; + } + + @Override + public LocalizedString getLocalizedName() { + return translator.localize(LocaleResources.VM_NUMA_TITLE); + } + + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/client-core/src/main/java/com/redhat/thermostat/vm/numa/client/core/locale/LocaleResources.java Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,55 @@ +/* + * 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.vm.numa.client.core.locale; + + +import com.redhat.thermostat.shared.locale.Translate; + +public enum LocaleResources { + VM_NUMA_TITLE, + VM_NUMA_TIME_LABEL, + VM_NUMA_MEMORY_LABEL, + VM_NUMA_UNAVAILABLE + ; + + static final String RESOURCE_BUNDLE = + "com.redhat.thermostat.vm.numa.client.core.locale.strings"; + + public static Translate<LocaleResources> createLocalizer() { + return new Translate<>(RESOURCE_BUNDLE, LocaleResources.class); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/client-core/src/main/resources/com/redhat/thermostat/vm/numa/client/core/locale/strings.properties Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,4 @@ +VM_NUMA_TITLE = NUMA +VM_NUMA_TIME_LABEL = Time +VM_NUMA_MEMORY_LABEL = Memory (MB) +VM_NUMA_UNAVAILABLE = NUMA is unavailable on this machine. \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/client-core/src/test/java/com/redhat/thermostat/vm/numa/client/core/VmNumaServiceImplTest.java Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,99 @@ +/* + * 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.vm.numa.client.core; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.junit.Before; +import org.junit.Test; + +import com.redhat.thermostat.common.ApplicationService; +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.HostRef; +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; + +public class VmNumaServiceImplTest { + + private VmNumaServiceImpl service; + + @Before + public void setup() { + ApplicationService appSvc = mock(ApplicationService.class); + TimerFactory timerFactory = mock(TimerFactory.class); + Timer timer = mock(Timer.class); + when(timerFactory.createTimer()).thenReturn(timer); + when(appSvc.getTimerFactory()).thenReturn(timerFactory); + + NumaDAO numaDAO = mock(NumaDAO.class); + VmNumaDAO vmNumaDAO = mock(VmNumaDAO.class); + + VmNumaViewProvider numaViewProvider = mock(VmNumaViewProvider.class); + VmNumaView view = mock(VmNumaView.class); + when(numaViewProvider.createView()).thenReturn(view); + + service = new VmNumaServiceImpl(appSvc, numaDAO, vmNumaDAO, numaViewProvider); + } + + @Test + public void verifyMemoryGroup() { + assertEquals(200, service.getOrderValue()); + } + + @Test + public void verifyFilter() { + assertNotNull(service.getFilter()); + } + + @Test + public void verifyInformationServiceController() { + HostRef hostRef = mock(HostRef.class); + when(hostRef.getAgentId()).thenReturn("agentId"); + VmRef vmRef = mock(VmRef.class); + when(vmRef.getVmId()).thenReturn("vmId"); + when(vmRef.getHostRef()).thenReturn(hostRef); + + assertTrue(service.getInformationServiceController(vmRef) instanceof VmNumaController); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/client-core/src/test/java/com/redhat/thermostat/vm/numa/client/core/VmNumaServiceTest.java Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,50 @@ +/* + * 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.vm.numa.client.core; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class VmNumaServiceTest { + + @Test + public void verifyServiceId() { + assertEquals("com.redhat.thermostat.vm.numa", VmNumaService.SERVICE_ID); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/client-core/src/test/java/com/redhat/thermostat/vm/numa/client/core/internal/ActivatorTest.java Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,68 @@ +/* + * 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.vm.numa.client.core.internal; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; + +import org.junit.Test; + +import com.redhat.thermostat.client.core.InformationService; +import com.redhat.thermostat.common.ApplicationService; +import com.redhat.thermostat.numa.common.NumaDAO; +import com.redhat.thermostat.testutils.StubBundleContext; +import com.redhat.thermostat.vm.numa.client.core.VmNumaServiceImpl; +import com.redhat.thermostat.vm.numa.client.core.VmNumaViewProvider; +import com.redhat.thermostat.vm.numa.common.VmNumaDAO; + +public class ActivatorTest { + + @Test + public void verifyServiceRegistered() throws Exception { + StubBundleContext stub = new StubBundleContext(); + stub.registerService(VmNumaDAO.class, mock(VmNumaDAO.class), null); + stub.registerService(ApplicationService.class, mock(ApplicationService.class), null); + stub.registerService(VmNumaViewProvider.class, mock(VmNumaViewProvider.class), null); + stub.registerService(NumaDAO.class, mock(NumaDAO.class), null); + + Activator activator = new Activator(); + + activator.start(stub); + + assertTrue(stub.isServiceRegistered(InformationService.class.getName(), VmNumaServiceImpl.class)); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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 @@ -0,0 +1,212 @@ +/* + * 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.vm.numa.client.core.internal; + +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; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.concurrent.TimeUnit; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; + +import com.redhat.thermostat.common.ActionEvent; +import com.redhat.thermostat.common.ActionListener; +import com.redhat.thermostat.common.ApplicationService; +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.model.DiscreteTimeData; +import com.redhat.thermostat.vm.numa.client.core.VmNumaView; +import com.redhat.thermostat.vm.numa.client.core.VmNumaViewProvider; +import com.redhat.thermostat.vm.numa.common.NumaMemoryLocations; +import com.redhat.thermostat.vm.numa.common.VmNumaDAO; +import com.redhat.thermostat.vm.numa.common.VmNumaNodeStat; +import com.redhat.thermostat.vm.numa.common.VmNumaStat; + +public class VmNumaControllerTest { + + private VmNumaController vmNumaController; + private Timer timer; + private VmNumaView view; + @SuppressWarnings("rawtypes") + private ArgumentCaptor<ActionListener> actionListener; + private ArgumentCaptor<Runnable> timerAction; + + private static final long TIMESTAMP = 1000; + private static final double DATA = 50; + private static final int NUM_NODES = 2; + + @Before + public void setup() { + ApplicationService appSvc = mock(ApplicationService.class); + TimerFactory timerFactory = mock(TimerFactory.class); + timer = mock(Timer.class); + timerAction = ArgumentCaptor.forClass(Runnable.class); + doNothing().when(timer).setAction(timerAction.capture()); + when(timerFactory.createTimer()).thenReturn(timer); + when(appSvc.getTimerFactory()).thenReturn(timerFactory); + + AgentId agentId = new AgentId("agent"); + VmId vmId = new VmId("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()); + + VmNumaViewProvider viewProvider = mock(VmNumaViewProvider.class); + view = mock(VmNumaView.class); + when(viewProvider.createView()).thenReturn(view); + + actionListener = ArgumentCaptor.forClass(ActionListener.class); + doNothing().when(view).addActionListener(actionListener.capture()); + + vmNumaController = new VmNumaController(appSvc, numaDAO, vmNumaDAO, vmId, agentId, viewProvider); + } + + private List<VmNumaStat> createStats() { + List<VmNumaStat> stats = new ArrayList<>(); + for (int i = 0; i < 5; i++) { + VmNumaStat stat = new VmNumaStat("agent"); + stat.setTimeStamp(i * TIMESTAMP); + stat.setVmId("vm"); + + List<VmNumaNodeStat> nodeStats = new ArrayList<>(); + for (int j = 0; j < NUM_NODES; j++) { + VmNumaNodeStat nodeStat = new VmNumaNodeStat(); + nodeStat.setNode(j); + nodeStat.setHeapMemory(i * DATA); + nodeStat.setPrivateMemory(i * DATA); + nodeStat.setStackMemory(i * DATA); + nodeStat.setHugeMemory(i * DATA); + nodeStats.add(nodeStat); + } + + stat.setVmNodeStats(nodeStats.toArray(new VmNumaNodeStat[0])); + stats.add(stat); + } + + return stats; + } + + @Test + public void verifyChartsAdded() { + verify(view).addChart(eq(NUM_NODES), eq("Huge")); + verify(view).addChart(eq(NUM_NODES), eq("Heap")); + verify(view).addChart(eq(NUM_NODES), eq("Stack")); + verify(view).addChart(eq(NUM_NODES), eq("Private")); + } + + @Test + public void verifyTimerSettings() { + verify(timer).setAction(any(Runnable.class)); + verify(timer).setSchedulingType(Timer.SchedulingType.FIXED_RATE); + verify(timer).setTimeUnit(TimeUnit.SECONDS); + verify(timer).setInitialDelay(0); + verify(timer).setDelay(5); + verifyNoMoreInteractions(timer); + } + + @Test + @SuppressWarnings({ "rawtypes", "unchecked" }) + public void verifyTimerAction() { + timerAction.getValue().run(); + for (int i = 0; i < NUM_NODES; i++) { + for (NumaMemoryLocations v : NumaMemoryLocations.values()) { + ArgumentCaptor<DiscreteTimeData> dataCaptor = ArgumentCaptor.forClass(DiscreteTimeData.class); + verify(view, times(5)).addData(eq(v.getName()), eq(i), dataCaptor.capture()); + + verifyValues(dataCaptor.getAllValues()); + } + } + } + + private void verifyValues(List<DiscreteTimeData> allValues) { + assertEquals(5, allValues.size()); + for (int i = 0; i < allValues.size(); i++) { + DiscreteTimeData data = allValues.get(i); + assertEquals(i * TIMESTAMP, data.getTimeInMillis()); + assertEquals(i * DATA, data.getData()); + } + + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void verifyViewActions() { + actionListener.getValue().actionPerformed(new ActionEvent(view, VmNumaView.Action.VISIBLE)); + verify(timer).start(); + + actionListener.getValue().actionPerformed(new ActionEvent(view, VmNumaView.Action.HIDDEN)); + verify(timer).stop(); + } + + @Test + public void testView() { + assertSame(view, vmNumaController.getView()); + } + + @Test + public void testLocalizedName() { + Locale defaultLocale = Locale.getDefault(); + try { + Locale.setDefault(Locale.US); + assertEquals("NUMA", vmNumaController.getLocalizedName().getContents()); + } finally { + Locale.setDefault(defaultLocale); + } + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/client-core/src/test/java/com/redhat/thermostat/vm/numa/client/core/locale/LocaleResourcesTest.java Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,53 @@ +/* + * 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.vm.numa.client.core.locale; + +import com.redhat.thermostat.testutils.AbstractLocaleResourcesTest; + +public class LocaleResourcesTest extends AbstractLocaleResourcesTest<LocaleResources> { + + @Override + protected Class<LocaleResources> getEnumClass() { + return LocaleResources.class; + } + + @Override + protected String getResourceBundle() { + return LocaleResources.RESOURCE_BUNDLE; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/client-swing/pom.xml Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,126 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + 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. + +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>thermostat-vm-numa</artifactId> + <groupId>com.redhat.thermostat</groupId> + <version>1.5.8-SNAPSHOT</version> + </parent> + <artifactId>thermostat-vm-numa-client-swing</artifactId> + <packaging>bundle</packaging> + <name>Thermostat VM NUMA Swing Client plugin</name> + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Private-Package>com.redhat.thermostat.vm.numa.client.swing.internal</Private-Package> + <Bundle-Activator>com.redhat.thermostat.vm.numa.client.swing.internal.Activator</Bundle-Activator> + <Bundle-Vendor>Red Hat, Inc.</Bundle-Vendor> + <Bundle-SymbolicName>com.redhat.thermostat.vm.numa.client.swing</Bundle-SymbolicName> + <!-- Do not autogenerate uses clauses in Manifests --> + <_nouses>true</_nouses> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-common-test</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.easytesting</groupId> + <artifactId>fest-swing</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>net.java.openjdk.cacio</groupId> + <artifactId>cacio-tta</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.core</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-common-core</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-vm-numa-client-core</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-client-core</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-client-swing</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-storage-core</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> +</project>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/client-swing/src/main/java/com/redhat/thermostat/vm/numa/client/swing/internal/Activator.java Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,57 @@ +/* + * 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.vm.numa.client.swing.internal; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +import com.redhat.thermostat.vm.numa.client.core.VmNumaViewProvider; + +public class Activator implements BundleActivator { + + @Override + public void start(BundleContext context) throws Exception { + VmNumaViewProvider viewProvider = new SwingVmNumaViewProvider(); + // Unregistered on Activator.stop + context.registerService(VmNumaViewProvider.class.getName(), viewProvider, null); + } + + @Override + public void stop(BundleContext context) throws Exception { + + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/client-swing/src/main/java/com/redhat/thermostat/vm/numa/client/swing/internal/SwingVmNumaViewProvider.java Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,47 @@ +/* + * 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.vm.numa.client.swing.internal; + +import com.redhat.thermostat.vm.numa.client.core.VmNumaView; +import com.redhat.thermostat.vm.numa.client.core.VmNumaViewProvider; + +public class SwingVmNumaViewProvider implements VmNumaViewProvider { + @Override + public VmNumaView createView() { + return new VmNumaPanel(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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 @@ -0,0 +1,207 @@ +/* + * 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.vm.numa.client.swing.internal; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; + +import org.jfree.chart.ChartFactory; +import org.jfree.chart.JFreeChart; +import org.jfree.chart.axis.NumberAxis; +import org.jfree.chart.plot.XYPlot; +import org.jfree.data.RangeType; +import org.jfree.data.time.FixedMillisecond; +import org.jfree.data.time.RegularTimePeriod; +import org.jfree.data.time.TimeSeries; +import org.jfree.data.time.TimeSeriesCollection; + +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; +import com.redhat.thermostat.vm.numa.client.core.locale.LocaleResources; + +public class VmNumaPanel extends VmNumaView implements SwingComponent { + + private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer(); + + private HeaderPanel visiblePanel; + + private static final int DEFAULT_VALUE = 10; + private static final TimeUnit DEFAULT_UNIT = TimeUnit.MINUTES; + + private Duration duration; + + private ActionNotifier<UserAction> userActionNotifier = new ActionNotifier<>(this); + + private final Map<String, TimeSeriesCollection> datasets = new HashMap<>(); + + private ThermostatChartPanel chartPanel; + + public VmNumaPanel() { + super(); + initializePanel(); + + new ComponentVisibilityNotifier().initialize(visiblePanel, notifier); + } + + private void initializePanel() { + visiblePanel = new HeaderPanel(); + visiblePanel.setHeader(translator.localize(LocaleResources.VM_NUMA_TITLE)); + + JPanel p = initializeChartsPanel(); + visiblePanel.setContent(p); + } + + private JPanel initializeChartsPanel() { + duration = new Duration(DEFAULT_VALUE, DEFAULT_UNIT); + chartPanel = new ThermostatChartPanel(duration); + + chartPanel.addPropertyChangeListener(ThermostatChartPanel.PROPERTY_VISIBLE_TIME_RANGE, new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + duration = (Duration) evt.getNewValue(); + userActionNotifier.fireAction(UserAction.USER_CHANGED_TIME_RANGE); + } + }); + + return chartPanel; + } + + private JFreeChart initializeChart(String title, TimeSeriesCollection collection) { + JFreeChart chart = ChartFactory.createTimeSeriesChart( + title, + translator.localize(LocaleResources.VM_NUMA_TIME_LABEL).getContents(), + translator.localize(LocaleResources.VM_NUMA_MEMORY_LABEL).getContents(), + collection, + true, false, false); + + NumberAxis rangeAxis = (NumberAxis) chart.getXYPlot().getRangeAxis(); + rangeAxis.setLowerBound(0.0); + rangeAxis.setRangeType(RangeType.POSITIVE); + + chart.getXYPlot().getRangeAxis().setAutoRange(true); + + chart.getXYPlot().getDomainAxis().setAutoRange(true); + + XYPlot plot = (XYPlot) chart.getPlot(); + plot.setBackgroundPaint(Color.WHITE); + chart.getPlot().setBackgroundImageAlpha(0.0f); + return chart; + } + + @Override + public void addChart(int numNumaNodes, String name) { + TimeSeriesCollection collection = new TimeSeriesCollection(); + datasets.put(name, collection); + + for (int i = 0; i < numNumaNodes; i++) { + TimeSeries series = new TimeSeries("Node: " + i); + collection.addSeries(series); + } + JFreeChart chart = initializeChart(name, collection); + chartPanel.addChart(chart); + } + + @Override + public void showNumaUnavailable() { + JPanel statusPanel = new JPanel(new BorderLayout()); + + String wrappedText = "<html>" + translator.localize(LocaleResources.VM_NUMA_UNAVAILABLE).getContents() + "</html>"; + JLabel descriptionLabel = new JLabel(wrappedText); + statusPanel.add(descriptionLabel, BorderLayout.PAGE_START); + + visiblePanel.setContent(statusPanel); + } + + @Override + public Component getUiComponent() { + return visiblePanel; + } + + @Override + public void addUserActionListener(ActionListener<UserAction> listener) { + userActionNotifier.addActionListener(listener); + } + + @Override + public void removeUserActionListener(ActionListener<UserAction> listener) { + userActionNotifier.removeActionListener(listener); + } + + @Override + public Duration getUserDesiredDuration() { + return duration; + } + + @Override + public void setVisibleDataRange(Duration duration) { + chartPanel.setTimeRangeToShow(duration); + } + + @Override + public void addData(final String seriesName, final int nodeNumber, final DiscreteTimeData<Double> data) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + TimeSeriesCollection collection = datasets.get(seriesName); + TimeSeries dataset = collection.getSeries("Node: " + nodeNumber); + RegularTimePeriod period = new FixedMillisecond(data.getTimeInMillis()); + if (dataset.getDataItem(period) == null) { + dataset.add(period, data.getData(), false); + } + dataset.fireSeriesChanged(); + } + }); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/client-swing/src/test/java/com/redhat/thermostat/vm/numa/client/swing/internal/ActivatorTest.java Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,57 @@ +/* + * 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.vm.numa.client.swing.internal; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.redhat.thermostat.testutils.StubBundleContext; +import com.redhat.thermostat.vm.numa.client.core.VmNumaViewProvider; + +public class ActivatorTest { + @Test + public void verifyServiceRegistered() throws Exception { + StubBundleContext context = new StubBundleContext(); + + Activator activator = new Activator(); + + activator.start(context); + + assertTrue(context.isServiceRegistered(VmNumaViewProvider.class.getName(), SwingVmNumaViewProvider.class)); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/client-swing/src/test/java/com/redhat/thermostat/vm/numa/client/swing/internal/VmNumaPanelTest.java Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,71 @@ +/* + * 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.vm.numa.client.swing.internal; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import java.awt.Container; + +import org.fest.swing.fixture.Containers; +import org.fest.swing.fixture.FrameFixture; +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.views.BasicView; +import com.redhat.thermostat.common.ActionEvent; +import com.redhat.thermostat.common.ActionListener; + +import net.java.openjdk.cacio.ctc.junit.CacioFESTRunner; + +@Category(CacioTest.class) +@RunWith(CacioFESTRunner.class) +public class VmNumaPanelTest { + @Test + public void testActionListener() { + VmNumaPanel numaPanel = new VmNumaPanel(); + ActionListener listener = mock(ActionListener.class); + numaPanel.addActionListener(listener); + FrameFixture frameFixture = Containers.frameFixtureFor((Container) numaPanel.getUiComponent()); + frameFixture.show(); + verify(listener).actionPerformed(new ActionEvent(numaPanel, BasicView.Action.VISIBLE)); + frameFixture.close(); + verify(listener).actionPerformed(new ActionEvent(numaPanel, BasicView.Action.VISIBLE)); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/common/pom.xml Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,117 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + 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. + +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>thermostat-vm-numa</artifactId> + <groupId>com.redhat.thermostat</groupId> + <version>1.5.8-SNAPSHOT</version> + </parent> + <artifactId>thermostat-vm-numa-common</artifactId> + <packaging>bundle</packaging> + <name>Thermostat VM NUMA Common plugin</name> + <build> + <resources> + <resource> + <directory>src/main/resources</directory> + <filtering>true</filtering> + <excludes> + <exclude>**/*.png</exclude> + </excludes> + </resource> + <resource> + <directory>src/main/resources</directory> + <filtering>false</filtering> + <includes> + <include>**/*.png</include> + </includes> + </resource> + </resources> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Bundle-Vendor>Red Hat, Inc.</Bundle-Vendor> + <Bundle-SymbolicName>com.redhat.thermostat.vm.numa.common</Bundle-SymbolicName> + <Bundle-Activator>com.redhat.thermostat.vm.numa.common.internal.Activator</Bundle-Activator> + <Export-Package> + com.redhat.thermostat.vm.numa.common + </Export-Package> + <Private-Package> + com.redhat.thermostat.vm.numa.common.internal + </Private-Package> + <!-- Do not autogenerate uses clauses in Manifests --> + <_nouses>true</_nouses> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-common-test</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.core</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-storage-core</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> +</project>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/common/src/main/java/com/redhat/thermostat/vm/numa/common/NumaMemoryLocations.java Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,55 @@ +/* + * 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.vm.numa.common; + +public enum NumaMemoryLocations { + HUGE("Huge"), + HEAP("Heap"), + STACK("Stack"), + PRIVATE("Private"), + ; + + private String name; + + private NumaMemoryLocations(String name) { + this.name = name; + } + + public String getName() { + return this.name; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/common/src/main/java/com/redhat/thermostat/vm/numa/common/VmNumaDAO.java Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,65 @@ +/* + * 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.vm.numa.common; + +import java.util.Arrays; +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; + +@Service +public interface VmNumaDAO { + + static final Key<VmNumaNodeStat[]> vmNodeStats = new Key<>("vmNodeStats"); + + static final 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); + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/common/src/main/java/com/redhat/thermostat/vm/numa/common/VmNumaNodeStat.java Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,101 @@ +/* + * 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.vm.numa.common; + +import com.redhat.thermostat.storage.core.Entity; +import com.redhat.thermostat.storage.core.Persist; +import com.redhat.thermostat.storage.model.Pojo; + +@Entity +public class VmNumaNodeStat implements Pojo { + + private int node; + private double hugeMemory; + private double heapMemory; + private double stackMemory; + private double privateMemory; + + @Persist + public int getNode() { + return node; + } + + @Persist + public void setNode(int node) { + this.node = node; + } + + @Persist + public double getHugeMemory() { + return hugeMemory; + } + + @Persist + public void setHugeMemory(double hugeMemory) { + this.hugeMemory = hugeMemory; + } + + @Persist + public double getHeapMemory() { + return heapMemory; + } + + @Persist + public void setHeapMemory(double heapMemory) { + this.heapMemory = heapMemory; + } + + @Persist + public double getStackMemory() { + return stackMemory; + } + + @Persist + public void setStackMemory(double stackMemory) { + this.stackMemory = stackMemory; + } + + @Persist + public double getPrivateMemory() { + return privateMemory; + } + + @Persist + public void setPrivateMemory(double privateMemory) { + this.privateMemory = privateMemory; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/common/src/main/java/com/redhat/thermostat/vm/numa/common/VmNumaStat.java Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,91 @@ +/* + * 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.vm.numa.common; + +import com.redhat.thermostat.storage.core.Entity; +import com.redhat.thermostat.storage.core.Persist; +import com.redhat.thermostat.storage.model.BasePojo; +import com.redhat.thermostat.storage.model.TimeStampedPojo; + +@Entity +public class VmNumaStat extends BasePojo implements TimeStampedPojo { + + private long timeStamp = -1; + + private String vmId; + private VmNumaNodeStat[] vmNodeStats = new VmNumaNodeStat[0]; + + public VmNumaStat() { + this(null); + } + + public VmNumaStat(String writerId) { + super(writerId); + } + + @Override + @Persist + public long getTimeStamp() { + return timeStamp; + } + + @Persist + public void setTimeStamp(long timeStamp) { + this.timeStamp = timeStamp; + } + + @Persist + public String getVmId() { + return vmId; + } + + @Persist + public void setVmId(String vmId) { + this.vmId = vmId; + } + + @Persist + public VmNumaNodeStat[] getVmNodeStats() { + return this.vmNodeStats; + } + + @Persist + public void setVmNodeStats(VmNumaNodeStat[] vmNodeStats) { + this.vmNodeStats = vmNodeStats; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/common/src/main/java/com/redhat/thermostat/vm/numa/common/internal/Activator.java Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,78 @@ +/* + * 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.vm.numa.common.internal; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; +import org.osgi.framework.ServiceRegistration; +import org.osgi.util.tracker.ServiceTracker; + +import com.redhat.thermostat.storage.core.Storage; +import com.redhat.thermostat.vm.numa.common.VmNumaDAO; + +public class Activator implements BundleActivator { + + private ServiceTracker tracker; + private ServiceRegistration reg; + + @Override + public void start(BundleContext context) throws Exception { + tracker = new ServiceTracker(context, Storage.class.getName(), null) { + @Override + public Object addingService(ServiceReference reference) { + Storage storage = (Storage) context.getService(reference); + VmNumaDAO vmNumaDAO = new VmNumaDAOImpl(storage); + reg = context.registerService(VmNumaDAO.class.getName(), vmNumaDAO, null); + return super.addingService(reference); + } + + @Override + public void removedService(ServiceReference reference, + Object service) { + reg.unregister(); + super.removedService(reference, service); + } + }; + tracker.open(); + } + + @Override + public void stop(BundleContext context) throws Exception { + tracker.close(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/common/src/main/java/com/redhat/thermostat/vm/numa/common/internal/VmNumaCategoryRegistration.java Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,52 @@ +/* + * 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.vm.numa.common.internal; + +import java.util.HashSet; +import java.util.Set; + +import com.redhat.thermostat.storage.core.auth.CategoryRegistration; +import com.redhat.thermostat.vm.numa.common.VmNumaDAO; + +public class VmNumaCategoryRegistration implements CategoryRegistration { + @Override + public Set<String> getCategoryNames() { + Set<String> categories = new HashSet<>(1); + categories.add(VmNumaDAO.vmNumaStatCategory.getName()); + return categories; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/common/src/main/java/com/redhat/thermostat/vm/numa/common/internal/VmNumaDAOImpl.java Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,117 @@ +/* + * 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.vm.numa.common.internal; + +import java.util.List; +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.Key; +import com.redhat.thermostat.storage.core.PreparedStatement; +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 { + + private static final Logger logger = LoggingUtils.getLogger(VmNumaDAOImpl.class); + + // ADD vm-numa-stats SET 'agentId' = ?s , \ + // 'vmId' = ?s , \ + // 'timeStamp' = ?l , \ + // 'vm-nodestats' = ?p[ + static final String DESC_ADD_VM_NUMA_STAT = "ADD " + vmNumaStatCategory.getName() + + " SET '" + Key.AGENT_ID.getName() + "' = ?s , " + + "'" + Key.VM_ID.getName() + "' = ?s , " + + "'" + Key.TIMESTAMP.getName() + "' = ?l , " + + "'" + vmNodeStats.getName() + "' = ?p["; + + private final Storage storage; + + private final VmTimeIntervalPojoListGetter<VmNumaStat> intervalGetter; + private final VmBoundaryPojoGetter<VmNumaStat> boundaryGetter; + + VmNumaDAOImpl(Storage storage) { + this.storage = storage; + storage.registerCategory(vmNumaStatCategory); + + this.intervalGetter = new VmTimeIntervalPojoListGetter<>(storage, vmNumaStatCategory); + this.boundaryGetter = new VmBoundaryPojoGetter<>(storage, vmNumaStatCategory); + } + + @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; + } + }); + } + + @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; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/common/src/main/java/com/redhat/thermostat/vm/numa/common/internal/VmNumaDAOImplStatementDescriptorRegistration.java Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,69 @@ +/* + * 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.vm.numa.common.internal; + +import java.util.HashSet; +import java.util.Set; + +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.StatementDescriptorRegistration; +import com.redhat.thermostat.vm.numa.common.VmNumaDAO; + +public class VmNumaDAOImplStatementDescriptorRegistration implements StatementDescriptorRegistration{ + static final String latestDescriptor = String.format(VmLatestPojoListGetter.VM_LATEST_QUERY_FORMAT, + VmNumaDAO.vmNumaStatCategory.getName()); + static final String rangeDescriptor = String.format(VmTimeIntervalPojoListGetter.VM_INTERVAL_QUERY_FORMAT, + VmNumaDAO.vmNumaStatCategory.getName()); + static final String latestStatDescriptor = String.format(VmBoundaryPojoGetter.DESC_NEWEST_VM_STAT, + VmNumaDAO.vmNumaStatCategory.getName()); + static final String oldestStatDescriptor = String.format(VmBoundaryPojoGetter.DESC_OLDEST_VM_STAT, + VmNumaDAO.vmNumaStatCategory.getName()); + + + @Override + public Set<String> getStatementDescriptors() { + Set<String> descs = new HashSet<>(); + descs.add(VmNumaDAOImpl.DESC_ADD_VM_NUMA_STAT); + descs.add(latestStatDescriptor); + descs.add(oldestStatDescriptor); + descs.add(latestDescriptor); + descs.add(rangeDescriptor); + return descs; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/common/src/main/resources/META-INF/services/com.redhat.thermostat.storage.core.auth.CategoryRegistration Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,1 @@ +com.redhat.thermostat.vm.numa.common.internal.VmNumaCategoryRegistration \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/common/src/main/resources/META-INF/services/com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,1 @@ +com.redhat.thermostat.vm.numa.common.internal.VmNumaDAOImplStatementDescriptorRegistration \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/common/src/test/java/com/redhat/thermostat/vm/numa/common/VmNumaDAOTest.java Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,59 @@ +/* + * 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.vm.numa.common; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.redhat.thermostat.storage.core.Category; + +public class VmNumaDAOTest { + + @Test + public void testCategory() { + Category<?> cat = VmNumaDAO.vmNumaStatCategory; + assertEquals("vm-numa-stats", cat.getName()); + assertEquals(VmNumaStat.class, cat.getDataClass()); + assertEquals(4, cat.getKeys().size()); + + assertEquals("agentId", cat.getKey("agentId").getName()); + assertEquals("vmId", cat.getKey("vmId").getName()); + assertEquals("timeStamp", cat.getKey("timeStamp").getName()); + assertEquals("vmNodeStats", cat.getKey("vmNodeStats").getName()); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/common/src/test/java/com/redhat/thermostat/vm/numa/common/VmNumaNodeStatTest.java Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,51 @@ +/* + * 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.vm.numa.common; + +import static org.junit.Assert.fail; + +import org.junit.Test; + +import com.redhat.thermostat.testutils.DataObjectTest; + +public class VmNumaNodeStatTest extends DataObjectTest { + + @Override + public Class<?>[] getDataClasses() { + return new Class[] { VmNumaNodeStat.class }; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/common/src/test/java/com/redhat/thermostat/vm/numa/common/VmNumaStatTest.java Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,47 @@ +/* + * 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.vm.numa.common; + +import com.redhat.thermostat.testutils.DataObjectTest; + +public class VmNumaStatTest extends DataObjectTest { + + @Override + public Class<?>[] getDataClasses() { + return new Class[] { VmNumaStat.class }; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/common/src/test/java/com/redhat/thermostat/vm/numa/common/internal/ActivatorTest.java Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,82 @@ +/* + * 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.vm.numa.common.internal; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; + +import org.junit.Test; + +import com.redhat.thermostat.storage.core.Storage; +import com.redhat.thermostat.testutils.StubBundleContext; +import com.redhat.thermostat.vm.numa.common.VmNumaDAO; + +public class ActivatorTest { + @Test + public void verifyActivatorDoesNotRegisterServiceOnMissingDeps() throws Exception { + StubBundleContext context = new StubBundleContext(); + + Activator activator = new Activator(); + + activator.start(context); + + assertEquals(0, context.getAllServices().size()); + assertEquals(1, context.getServiceListeners().size()); + + activator.stop(context); + } + + @Test + public void verifyActivatorRegistersServices() throws Exception { + StubBundleContext context = new StubBundleContext(); + Storage storage = mock(Storage.class); + + context.registerService(Storage.class, storage, null); + + Activator activator = new Activator(); + + activator.start(context); + + assertTrue(context.isServiceRegistered(VmNumaDAO.class.getName(), VmNumaDAOImpl.class)); + + activator.stop(context); + + assertEquals(0, context.getServiceListeners().size()); + assertEquals(1, context.getAllServices().size()); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/common/src/test/java/com/redhat/thermostat/vm/numa/common/internal/VmNumaCategoryRegistrationTest.java Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,66 @@ +/* + * 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.vm.numa.common.internal; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.Set; + +import org.junit.Test; + +import com.redhat.thermostat.storage.core.auth.CategoryRegistration; +import com.redhat.thermostat.testutils.ServiceLoaderTest; +import com.redhat.thermostat.vm.numa.common.VmNumaDAO; + +public class VmNumaCategoryRegistrationTest extends ServiceLoaderTest<CategoryRegistration> { + + public VmNumaCategoryRegistrationTest() { + super(CategoryRegistration.class, STORAGE_SERVICES, VmNumaCategoryRegistration.class); + } + + @Test + public void registersAllCategories() { + VmNumaCategoryRegistration reg = new VmNumaCategoryRegistration(); + Set<String> categories = reg.getCategoryNames(); + assertEquals(1, categories.size()); + assertFalse("null descriptor not allowed", categories.contains(null)); + assertTrue(categories.contains(VmNumaDAO.vmNumaStatCategory.getName())); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/common/src/test/java/com/redhat/thermostat/vm/numa/common/internal/VmNumaDAOImplStatementDescriptorRegistrationTest.java Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,63 @@ +/* + * 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.vm.numa.common.internal; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +import java.util.Set; + +import org.junit.Test; + +import com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration; +import com.redhat.thermostat.testutils.ServiceLoaderTest; + +public class VmNumaDAOImplStatementDescriptorRegistrationTest extends ServiceLoaderTest<StatementDescriptorRegistration> { + + public VmNumaDAOImplStatementDescriptorRegistrationTest() { + super(StatementDescriptorRegistration.class, STORAGE_SERVICES, VmNumaDAOImplStatementDescriptorRegistration.class); + } + + @Test + public void registersAllDescriptors() { + VmNumaDAOImplStatementDescriptorRegistration reg = new VmNumaDAOImplStatementDescriptorRegistration(); + Set<String> descriptors = reg.getStatementDescriptors(); + assertEquals(5, descriptors.size()); + assertFalse("null descriptor not allowed", descriptors.contains(null)); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/common/src/test/java/com/redhat/thermostat/vm/numa/common/internal/VmNumaDAOImplTest.java Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,74 @@ +/* + * 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.vm.numa.common.internal; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import org.junit.Before; +import org.junit.Test; + +import com.redhat.thermostat.storage.core.Storage; +import com.redhat.thermostat.vm.numa.common.VmNumaDAO; + +public class VmNumaDAOImplTest { + private VmNumaDAO vmNumaDAO; + private Storage storage; + + @Before + public void setUp() { + storage = mock(Storage.class); + vmNumaDAO = new VmNumaDAOImpl(storage); + } + + @Test + public void preparedQueryDescriptorsAreSane() { + String addNumaStat = "ADD vm-numa-stats SET 'agentId' = ?s , " + + "'vmId' = ?s , " + + "'timeStamp' = ?l , " + + "'vmNodeStats' = ?p["; + assertEquals(addNumaStat, VmNumaDAOImpl.DESC_ADD_VM_NUMA_STAT); + } + + @Test + public void testRegisterCategory() { + verify(storage).registerCategory(VmNumaDAO.vmNumaStatCategory); + } + + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/distribution/pom.xml Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,113 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + 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. + +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-vm-numa</artifactId> + <version>1.5.8-SNAPSHOT</version> + </parent> + + <artifactId>thermostat-vm-numa-distribution</artifactId> + <packaging>pom</packaging> + + <name>Thermostat VM NUMA plugin distribution</name> + + <properties> + <thermostat.plugin>vm-numa</thermostat.plugin> + </properties> + + <build> + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <dependencies> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-assembly</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + <configuration> + <descriptorRefs> + <descriptorRef>plugin-assembly</descriptorRef> + </descriptorRefs> + <appendAssemblyId>false</appendAssemblyId> + </configuration> + <executions> + <execution> + <id>assemble-plugin</id> + <phase>package</phase> + <goals> + <goal>single</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + + <!-- Explicitly list all plug-in artifacts, transitive dependencies + are not included in assembly. --> + <dependencies> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-vm-numa-common</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-vm-numa-client-core</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-vm-numa-client-swing</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-vm-numa-agent</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + +</project> +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/distribution/thermostat-plugin.xml Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,60 @@ +<?xml version="1.0"?> +<!-- + + 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. + +--> +<plugin xmlns="http://icedtea.classpath.org/thermostat/plugins/v1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://icedtea.classpath.org/thermostat/plugins/v1.0 thermostat-plugin.xsd"> + <extensions> + <extension> + <name>gui</name> + <bundles> + <bundle><symbolic-name>com.redhat.thermostat.vm.numa.common</symbolic-name><version>${project.version}</version></bundle> + <bundle><symbolic-name>com.redhat.thermostat.vm.numa.client.core</symbolic-name><version>${project.version}</version></bundle> + <bundle><symbolic-name>com.redhat.thermostat.vm.numa.client.swing</symbolic-name><version>${project.version}</version></bundle> + </bundles> + </extension> + <extension> + <name>agent</name> + <bundles> + <bundle><symbolic-name>com.redhat.thermostat.vm.numa.agent</symbolic-name><version>${project.version}</version></bundle> + <bundle><symbolic-name>com.redhat.thermostat.vm.numa.common</symbolic-name><version>${project.version}</version></bundle> + </bundles> + </extension> + </extensions> +</plugin> +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-numa/pom.xml Thu Jun 09 08:58:57 2016 -0400 @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + 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. + +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat</artifactId> + <version>1.5.8-SNAPSHOT</version> + </parent> + + <artifactId>thermostat-vm-numa</artifactId> + <packaging>pom</packaging> + + <name>Thermostat VM NUMA plugin</name> + + <modules> + <module>agent</module> + <module>common</module> + <module>client-core</module> + <module>client-swing</module> + <module>distribution</module> + </modules> + +</project> +
--- a/web/war/pom.xml Tue Jun 07 11:55:47 2016 -0400 +++ b/web/war/pom.xml Thu Jun 09 08:58:57 2016 -0400 @@ -176,6 +176,11 @@ <artifactId>thermostat-vm-profiler-common</artifactId> <version>${project.version}</version> </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-vm-numa-common</artifactId> + <version>${project.version}</version> + </dependency> </dependencies> <build>