Mercurial > hg > release > thermostat-0.4
changeset 548:e47c726e6e60
Eclipse client prototype.
This commit introduces a simple Eclipse plug-in based Thermostat client. A demo
of it can be seen here:
http://jerboaa.fedorapeople.org/demo/thermostat/eclipse_prototype_20120816.webm
Reviewed-by: vanaltj, neugens
Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2012-August/002667.html
PR1082
PR1087
PR1088
line wrap: on
line diff
--- a/client/eclipse/com.redhat.thermostat.eclipse.boot/pom.xml Fri Aug 17 13:13:47 2012 +0200 +++ b/client/eclipse/com.redhat.thermostat.eclipse.boot/pom.xml Fri Aug 17 15:34:32 2012 +0200 @@ -9,8 +9,8 @@ </parent> <groupId>com.redhat.thermostat.eclipse.parent</groupId> <artifactId>com.redhat.thermostat.eclipse.boot</artifactId> + <packaging>eclipse-plugin</packaging> <version>0.4.0-SNAPSHOT</version> - <packaging>eclipse-plugin</packaging> <name>Thermostat Eclipse Client Boot Package</name>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/eclipse/com.redhat.thermostat.eclipse.test/.classpath Fri Aug 17 15:34:32 2012 +0200 @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="src" path="src"/> + <classpathentry kind="output" path="bin"/> +</classpath>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/eclipse/com.redhat.thermostat.eclipse.test/.project Fri Aug 17 15:34:32 2012 +0200 @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>com.redhat.thermostat.eclipse.test</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/eclipse/com.redhat.thermostat.eclipse.test/.settings/org.eclipse.jdt.core.prefs Fri Aug 17 15:34:32 2012 +0200 @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.7
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/eclipse/com.redhat.thermostat.eclipse.test/META-INF/MANIFEST.MF Fri Aug 17 15:34:32 2012 +0200 @@ -0,0 +1,12 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Version: 0.4.0.qualifier +Fragment-Host: com.redhat.thermostat.eclipse;bundle-version="0.4.0.qualifier" +Bundle-Name: Eclipse client tests +Bundle-SymbolicName: com.redhat.thermostat.eclipse.test +Bundle-Vendor: Redhat Inc. +Require-Bundle: org.eclipse.jdt.core, + org.junit;bundle-version="3.8.2" +Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +Import-Package: org.mockito, + org.mockito.stubbing
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/eclipse/com.redhat.thermostat.eclipse.test/build.properties Fri Aug 17 15:34:32 2012 +0200 @@ -0,0 +1,4 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/eclipse/com.redhat.thermostat.eclipse.test/fedora-packages.txt Fri Aug 17 15:34:32 2012 +0200 @@ -0,0 +1,5 @@ +The following Fedora packages required updates (OSGi metadata) in order +for this fragment to work: +- mockito +- hamcrest +- cglib \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/eclipse/com.redhat.thermostat.eclipse.test/pom.xml Fri Aug 17 15:34:32 2012 +0200 @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>thermostat-eclipse-parent</artifactId> + <groupId>com.redhat.thermostat.eclipse.parent</groupId> + <version>0.4.0-SNAPSHOT</version> + </parent> + <groupId>com.redhat.thermostat.eclipse.parent</groupId> + <artifactId>com.redhat.thermostat.eclipse.test</artifactId> + <packaging>eclipse-test-plugin</packaging> + <version>0.4.0-SNAPSHOT</version> + + <name>Thermostat Eclipse Client Tests</name> + + <dependencies> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-common-core</artifactId> + <version>0.4.0-SNAPSHOT</version> + </dependency> + </dependencies> + +</project>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/eclipse/com.redhat.thermostat.eclipse.test/src/com/redhat/thermostat/eclipse/model/HostVmsTreeContentProviderTest.java Fri Aug 17 15:34:32 2012 +0200 @@ -0,0 +1,211 @@ +/* + * Copyright 2012 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.eclipse.model; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.redhat.thermostat.common.HostsVMsLoader; +import com.redhat.thermostat.common.dao.HostRef; +import com.redhat.thermostat.common.dao.VmRef; + +public class HostVmsTreeContentProviderTest { + + private HostsVmsTreeContentProvider treeProvider; + private HostRef hostRef; + HostsVMsLoader loader; + + @Before + public void setUp() throws Exception { + loader = mock(HostsVMsLoader.class); + hostRef = mock(HostRef.class); + treeProvider = new HostsVmsTreeContentProvider(loader); + } + + @After + public void tearDown() throws Exception { + hostRef = null; + treeProvider = null; + loader = null; + } + + @Test + public void canGetHosts() { + List<HostRef> expectedHosts = new ArrayList<>(); + HostRef hostRef1 = mock(HostRef.class); + HostRef hostRef2 = mock(HostRef.class); + expectedHosts.add(hostRef1); + expectedHosts.add(hostRef2); + + when(loader.getHosts()).thenReturn(expectedHosts); + Object[] children = treeProvider.getChildren(new HostsVmsTreeRoot()); + verifySameHosts(children, expectedHosts); + + children = treeProvider.getChildren(new String("ignored")); + assertTrue(children.length == 0); + } + + @Test + public void canGetVms() { + List<VmRef> expectedVms = new ArrayList<>(); + expectedVms.add(mock(VmRef.class)); + expectedVms.add(mock(VmRef.class)); + when(loader.getVMs(hostRef)).thenReturn(expectedVms); + Object[] children = treeProvider.getChildren(hostRef); + verifySameVms(children, expectedVms); + } + + @Test + public void canGetElements() { + List<HostRef> expectedHosts = new ArrayList<>(); + HostRef hostRef1 = mock(HostRef.class); + HostRef hostRef2 = mock(HostRef.class); + expectedHosts.add(hostRef1); + expectedHosts.add(hostRef2); + + when(loader.getHosts()).thenReturn(expectedHosts); + Object[] children = treeProvider.getElements(new HostsVmsTreeRoot()); + verifySameHosts(children, expectedHosts); + } + + @Test + public void canGetRoot() { + assertNull(treeProvider.getParent(new HostsVmsTreeRoot())); + } + + @Test + public void canGetVmParent() { + List<HostRef> expectedHosts = new ArrayList<>(); + HostRef hostRef1 = mock(HostRef.class); + HostRef hostRef2 = mock(HostRef.class); + expectedHosts.add(hostRef1); + expectedHosts.add(hostRef2); + List<VmRef> expectedVms = new ArrayList<>(); + VmRef vm = mock(VmRef.class); + expectedVms.add(mock(VmRef.class)); + expectedVms.add(vm); + expectedVms.add(mock(VmRef.class)); + when(loader.getHosts()).thenReturn(expectedHosts); + when(loader.getVMs(hostRef1)).thenReturn(expectedVms); + treeProvider = new HostsVmsTreeContentProvider(loader); + assertEquals(hostRef1, treeProvider.getParent(vm)); + } + + /** + * Implicitly tests inputChanged() as well + */ + @Test + public void canGetHostParent() { + List<HostRef> expectedHosts = new ArrayList<>(); + HostRef hostRef1 = mock(HostRef.class); + HostRef hostRef2 = mock(HostRef.class); + expectedHosts.add(hostRef1); + expectedHosts.add(hostRef2); + + // need this for reverse look-up map building + // which is triggered when inputChanged() is called + List<VmRef> expectedVms = new ArrayList<>(); + VmRef vm = mock(VmRef.class); + expectedVms.add(mock(VmRef.class)); + expectedVms.add(vm); + expectedVms.add(mock(VmRef.class)); + when(loader.getVMs(hostRef)).thenReturn(expectedVms); + when(loader.getHosts()).thenReturn(expectedHosts); + + // need to call inputChanged in order to set root + // this is safe to do since treeViewer's setInput() method + // triggers the same action. + HostsVmsTreeRoot root = new HostsVmsTreeRoot(); + treeProvider.inputChanged(null, null, root); + assertEquals(root, treeProvider.getParent(hostRef1)); + } + + @Test + public void hasChildren() { + List<HostRef> expectedHosts = new ArrayList<>(); + HostRef hostRef1 = mock(HostRef.class); + HostRef hostRef2 = mock(HostRef.class); + expectedHosts.add(hostRef1); + expectedHosts.add(hostRef2); + when(loader.getHosts()).thenReturn(expectedHosts); + assertTrue(treeProvider.hasChildren(new HostsVmsTreeRoot())); + expectedHosts = new ArrayList<>(); + when(loader.getHosts()).thenReturn(expectedHosts); + assertFalse(treeProvider.hasChildren(new HostsVmsTreeRoot())); + + List<VmRef> expectedVms = new ArrayList<>(); + VmRef vm = mock(VmRef.class); + expectedVms.add(mock(VmRef.class)); + expectedVms.add(vm); + expectedVms.add(mock(VmRef.class)); + when(loader.getVMs(hostRef)).thenReturn(expectedVms); + assertTrue(treeProvider.hasChildren(hostRef)); + expectedVms = new ArrayList<>(); + when(loader.getVMs(hostRef)).thenReturn(expectedVms); + assertFalse(treeProvider.hasChildren(hostRef)); + + // VMs don't have children + assertFalse(treeProvider.hasChildren(mock(VmRef.class))); + } + + private void verifySameHosts(Object[] children, List<HostRef> expectedHosts) { + assertEquals(children.length, expectedHosts.size()); + for (int i = 0; i < children.length; i++) { + assertTrue(children[i] instanceof HostRef); + assertEquals(children[i], expectedHosts.get(i)); + } + } + + private void verifySameVms(Object[] children, List<VmRef> expectedHosts) { + assertEquals(children.length, expectedHosts.size()); + for (int i = 0; i < children.length; i++) { + assertTrue(children[i] instanceof VmRef); + assertEquals(children[i], expectedHosts.get(i)); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/eclipse/com.redhat.thermostat.eclipse.test/src/com/redhat/thermostat/eclipse/model/HostsVmsLabelProviderTest.java Fri Aug 17 15:34:32 2012 +0200 @@ -0,0 +1,86 @@ +/* + * Copyright 2012 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.eclipse.model; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import com.redhat.thermostat.common.dao.HostRef; +import com.redhat.thermostat.common.dao.VmRef; + +public class HostsVmsLabelProviderTest { + + private HostsVmsLabelProvider labelProvider; + + @Before + public void setUp() { + labelProvider = new HostsVmsLabelProvider(); + } + + @After + public void tearDown() { + labelProvider = null; + } + + @Test + public void canGetLabels() { + String hostName = "host1"; + HostRef host = mock(HostRef.class); + when(host.getHostName()).thenReturn(hostName); + assertEquals(hostName, labelProvider.getText(host)); + String vmName = "vm1"; + VmRef vm = mock(VmRef.class); + when(vm.getName()).thenReturn(vmName); + } + + @Test(expected = RuntimeException.class) + public void getLabelthrowsException() { + labelProvider.getText(new HostsVmsTreeRoot()); + } + + @Test + public void canGetImage() { + assertNull(labelProvider.getImage(mock(HostRef.class))); + assertNull(labelProvider.getImage(mock(VmRef.class))); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/eclipse/com.redhat.thermostat.eclipse/.classpath Fri Aug 17 15:34:32 2012 +0200 @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="src" path="src"/> + <classpathentry kind="output" path="bin"/> +</classpath>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/eclipse/com.redhat.thermostat.eclipse/.project Fri Aug 17 15:34:32 2012 +0200 @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>com.redhat.thermostat.eclipse</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/eclipse/com.redhat.thermostat.eclipse/META-INF/MANIFEST.MF Fri Aug 17 15:34:32 2012 +0200 @@ -0,0 +1,19 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Thermostat Eclipse Client +Bundle-Activator: com.redhat.thermostat.eclipse.Activator +Bundle-SymbolicName: com.redhat.thermostat.eclipse;singleton:=true +Bundle-Version: 0.4.0.qualifier +Bundle-Vendor: Red Hat Inc. +Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +Bundle-ActivationPolicy: lazy +Require-Bundle: org.eclipse.core.runtime;bundle-version="3.8.0", + org.eclipse.ui;bundle-version="3.103.0" +Import-Package: com.mongodb, + com.redhat.thermostat.common, + com.redhat.thermostat.common.appctx, + com.redhat.thermostat.common.config, + com.redhat.thermostat.common.dao, + com.redhat.thermostat.common.model, + com.redhat.thermostat.common.storage +Eclipse-ExtensibleAPI: true
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/eclipse/com.redhat.thermostat.eclipse/build.properties Fri Aug 17 15:34:32 2012 +0200 @@ -0,0 +1,5 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/eclipse/com.redhat.thermostat.eclipse/plugin.xml Fri Aug 17 15:34:32 2012 +0200 @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?eclipse version="3.5"?> +<!-- + + Copyright 2012 Red Hat, Inc. + + This file is part of Thermostat. + + Thermostat is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 2, or (at your + option) any later version. + + Thermostat is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Thermostat; see the file COPYING. If not see + <http://www.gnu.org/licenses/>. + + Linking this code with other modules is making a combined work + based on this code. Thus, the terms and conditions of the GNU + General Public License cover the whole combination. + + As a special exception, the copyright holders of this code give + you permission to link this code with independent modules to + produce an executable, regardless of the license terms of these + independent modules, and to copy and distribute the resulting + executable under terms of your choice, provided that you also + meet, for each linked independent module, the terms and conditions + of the license of that module. An independent module is a module + which is not derived from or based on this code. If you modify + this code, you may extend this exception to your version of the + library, but you are not obligated to do so. If you do not wish + to do so, delete this exception statement from your version. + +--> +<plugin> + <extension + point="org.eclipse.ui.views"> + <category + id="com.redhat.thermostat.eclipse.main" + name="Thermostat"> + </category> + <view + category="com.redhat.thermostat.eclipse.main" + class="com.redhat.thermostat.eclipse.views.HostsVmsTreeViewPart" + id="com.redhat.thermostat.eclipse.vmtree" + name="Hosts/VMs" + restorable="true"> + </view> + <view + category="com.redhat.thermostat.eclipse.main" + class="com.redhat.thermostat.eclipse.views.HostOverviewViewPart" + id="com.redhat.thermostat.eclipse.mainContainer" + name="Host Overview" + restorable="true"> + </view> + </extension> +</plugin>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/eclipse/com.redhat.thermostat.eclipse/pom.xml Fri Aug 17 15:34:32 2012 +0200 @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>thermostat-eclipse-parent</artifactId> + <groupId>com.redhat.thermostat.eclipse.parent</groupId> + <version>0.4.0-SNAPSHOT</version> + </parent> + <groupId>com.redhat.thermostat.eclipse.parent</groupId> + <artifactId>com.redhat.thermostat.eclipse</artifactId> + <packaging>eclipse-plugin</packaging> + <version>0.4.0-SNAPSHOT</version> + + <name>Thermostat Eclipse Client</name> + + <dependencies> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-common-core</artifactId> + <version>0.4.0-SNAPSHOT</version> + </dependency> + </dependencies> + +</project>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/eclipse/com.redhat.thermostat.eclipse/src/com/redhat/thermostat/eclipse/Activator.java Fri Aug 17 15:34:32 2012 +0200 @@ -0,0 +1,155 @@ +/* + * Copyright 2012 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.eclipse; + +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +import com.redhat.thermostat.common.appctx.ApplicationContext; +import com.redhat.thermostat.common.storage.Connection; + +/** + * The activator class controls the plug-in life cycle + */ +public class Activator extends AbstractUIPlugin { + + // Storage connection status + private volatile boolean connected = false; + + // The plug-in ID + public static final String PLUGIN_ID = "com.redhat.thermostat.eclipse"; //$NON-NLS-1$ + + // The shared instance + private static Activator plugin; + + /** + * The constructor + */ + public Activator() { + } + + public boolean isConnected() { + return connected; + } + + public void setConnected(boolean connected) { + this.connected = connected; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext + * ) + */ + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext + * ) + */ + public void stop(BundleContext context) throws Exception { + if (isConnected()) { + Connection connection = ApplicationContext.getInstance() + .getDAOFactory().getConnection(); + connection.disconnect(); + } + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() { + return plugin; + } + + /** + * + * @return {@code true} when platform was started in debug mode ( + * {@code -debug} switch) and + * {@code com.redhat.thermostat.eclipse/debug=true} is set in some + * .options file either in $HOME/.options or $(pwd)/.options. + */ + public static boolean inDebugMode() { + if (Platform.inDebugMode()) { + String debugOption = Platform.getDebugOption(PLUGIN_ID + "/debug"); //$NON-NLS-1$ + if (debugOption != null && debugOption.equals("true")) { //$NON-NLS-1$ + return true; + } + } + return false; + } + + public IWorkbenchPage getActivePage() { + return internalGetActivePage(); + } + + private IWorkbenchPage internalGetActivePage() { + IWorkbenchWindow window = getWorkbench().getActiveWorkbenchWindow(); + if (window == null) + return null; + return window.getActivePage(); + } + + /** + * Returns an image descriptor for the image file at the given plug-in + * relative path + * + * @param path + * the path + * @return the image descriptor + */ + public static ImageDescriptor getImageDescriptor(String path) { + return imageDescriptorFromPlugin(PLUGIN_ID, path); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/eclipse/com.redhat.thermostat.eclipse/src/com/redhat/thermostat/eclipse/ConnectionConfiguration.java Fri Aug 17 15:34:32 2012 +0200 @@ -0,0 +1,55 @@ +/* + * Copyright 2012 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.eclipse; + +import com.redhat.thermostat.common.config.StartupConfiguration; + +public class ConnectionConfiguration implements StartupConfiguration { + + private String dbUrl; + + // FIXME: Adapt to more dynamic requirements + public ConnectionConfiguration(String dbUrl) { + this.dbUrl = dbUrl; + } + + @Override + public String getDBConnectionString() { + return dbUrl; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/eclipse/com.redhat.thermostat.eclipse/src/com/redhat/thermostat/eclipse/LoggerFacility.java Fri Aug 17 15:34:32 2012 +0200 @@ -0,0 +1,94 @@ +/* + * Copyright 2012 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.eclipse; + +import org.eclipse.core.runtime.ILog; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; + +public class LoggerFacility { + + private ILog log; + private static LoggerFacility instance; + private static boolean isLoggingEnabled; // want default of false + + private LoggerFacility() { + log = Activator.getDefault().getLog(); + isLoggingEnabled = Activator.inDebugMode(); + } + + /** + * Get a LoggerFacility singleton. + * + * @return The singleton instance. + */ + public static LoggerFacility getInstance() { + if (instance == null) { + instance = new LoggerFacility(); + } + return instance; + } + + /** + * Logs messages with the given severity. + * + * @param message + * The human readable localized message. + * @param throwable + * The exception which occurred. + */ + public void log(int severity, String message, Throwable throwable) { + if (isLoggingEnabled) { + log.log(new Status(severity, Activator.PLUGIN_ID, message, + throwable)); + } + } + + /** + * Logs messages with the given severity. + * + * @param message + * A human readable localized message. + * @param severity + * A suitable severity. See {@link IStatus}. + */ + public void log(int severity, String message) { + if (isLoggingEnabled) { + log.log(new Status(severity, Activator.PLUGIN_ID, message)); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/eclipse/com.redhat.thermostat.eclipse/src/com/redhat/thermostat/eclipse/model/HostsVmsLabelProvider.java Fri Aug 17 15:34:32 2012 +0200 @@ -0,0 +1,78 @@ +/* + * Copyright 2012 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.eclipse.model; + +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.swt.graphics.Image; + +import com.redhat.thermostat.common.dao.HostRef; +import com.redhat.thermostat.common.dao.VmRef; + +public class HostsVmsLabelProvider extends LabelProvider { + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.LabelProvider#getImage(java.lang.Object) + */ + @Override + public Image getImage(Object element) { + return null; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object) + */ + @Override + public String getText(Object element) { + if (element instanceof HostRef) { + return ((HostRef) element).getHostName(); + } else if (element instanceof VmRef) { + return ((VmRef) element).getName(); + } else { + throw unknownElement(element); + } + } + + private RuntimeException unknownElement(Object element) { + return new RuntimeException("Unknown type of element in tree of type " + + element.getClass().getName()); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/eclipse/com.redhat.thermostat.eclipse/src/com/redhat/thermostat/eclipse/model/HostsVmsTreeContentProvider.java Fri Aug 17 15:34:32 2012 +0200 @@ -0,0 +1,139 @@ +/* + * Copyright 2012 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.eclipse.model; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; + +import com.redhat.thermostat.common.HostsVMsLoader; +import com.redhat.thermostat.common.dao.HostRef; +import com.redhat.thermostat.common.dao.VmRef; + +public class HostsVmsTreeContentProvider implements ITreeContentProvider { + + private static final Object[] EMPTY_LIST = new Object[0]; + + private HostsVMsLoader loader; + private Map<VmRef, HostRef> reverseLookupMap; + private HostsVmsTreeRoot root; + + public HostsVmsTreeContentProvider(HostsVMsLoader loader) { + this.loader = loader; + this.reverseLookupMap = buildReverseLookupMap(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.IContentProvider#dispose() + */ + @Override + public void dispose() { + // nothing + } + + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + if (newInput instanceof HostsVmsTreeRoot) { + root = (HostsVmsTreeRoot) newInput; + } + // refresh reverse look-up + this.reverseLookupMap = buildReverseLookupMap(); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.viewers.ITreeContentProvider#getElements(java.lang. + * Object) + */ + @Override + public Object[] getElements(Object root) { + return getChildren(root); + } + + @Override + public Object[] getChildren(Object parentElement) { + if (parentElement instanceof HostsVmsTreeRoot) { + return loader.getHosts().toArray(); + } else if (parentElement instanceof HostRef) { + HostRef hostRef = (HostRef) parentElement; + return loader.getVMs(hostRef).toArray(); + } else { + return EMPTY_LIST; + } + } + + @Override + public Object getParent(Object element) { + if (element instanceof HostsVmsTreeRoot) { + return null; + } else if (element instanceof HostRef) { + return root; + } else if (element instanceof VmRef) { + return this.reverseLookupMap.get(element); + } + return null; + } + + @Override + public boolean hasChildren(Object element) { + if (element instanceof HostsVmsTreeRoot) { + return loader.getHosts().size() > 0; + } else if (element instanceof HostRef) { + HostRef host = (HostRef) element; + return loader.getVMs(host).size() > 0; + } else { + // VM refs don't have children + return false; + } + } + + private Map<VmRef, HostRef> buildReverseLookupMap() { + Map<VmRef, HostRef> lookupMap = new HashMap<>(); + for (HostRef ref : loader.getHosts()) { + for (VmRef vmRef : loader.getVMs(ref)) { + lookupMap.put(vmRef, ref); + } + } + return lookupMap; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/eclipse/com.redhat.thermostat.eclipse/src/com/redhat/thermostat/eclipse/model/HostsVmsTreeRoot.java Fri Aug 17 15:34:32 2012 +0200 @@ -0,0 +1,44 @@ +/* + * Copyright 2012 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.eclipse.model; + +/** + * A dummy root object, since the Hosts don't have a real root. + */ +public class HostsVmsTreeRoot { + // nothing +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/eclipse/com.redhat.thermostat.eclipse/src/com/redhat/thermostat/eclipse/views/HostOverviewViewPart.java Fri Aug 17 15:34:32 2012 +0200 @@ -0,0 +1,401 @@ +/* + * Copyright 2012 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.eclipse.views; + +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.ui.ISelectionListener; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.part.PageBook; +import org.eclipse.ui.part.ViewPart; + +import com.redhat.thermostat.common.appctx.ApplicationContext; +import com.redhat.thermostat.common.dao.DAOFactory; +import com.redhat.thermostat.common.dao.HostInfoDAO; +import com.redhat.thermostat.common.dao.HostRef; +import com.redhat.thermostat.common.dao.NetworkInterfaceInfoDAO; +import com.redhat.thermostat.common.dao.Ref; +import com.redhat.thermostat.common.dao.VmRef; +import com.redhat.thermostat.common.model.HostInfo; +import com.redhat.thermostat.common.model.NetworkInterfaceInfo; +import com.redhat.thermostat.eclipse.Activator; + +public class HostOverviewViewPart extends ViewPart { + + private static final int FIRST_COLUMN_WIDTH = 150; + private final String STR_UNKNOWN = "UNKNOWN"; + private PageBook pageBook; + // VM page + private Composite vmPage; + private Label vmName; + private Composite notConnectedPage; + // Main compositie + private ScrolledComposite mainScrollPage; + private Label hostname; + private Label procModel; + private Label procCoreCount; + private Label totalMemory; + private TableViewer networkInterfaces; + private Label osName; + private Label osKernel; + private ISelection oldSelection = null; + + // The listener we register with the selection service in order to listen + // for + // VmTreeView selection changes. + private ISelectionListener listener = new ISelectionListener() { + public void selectionChanged(IWorkbenchPart sourcepart, + ISelection selection) { + // only react upon hosts/vms tree changes. Then only if the selected + // element + // actually changed + if (sourcepart instanceof HostsVmsTreeViewPart + && !selection.equals(oldSelection)) { + oldSelection = selection; + Ref ref = getRefFromSelection(selection); + if (Activator.getDefault().isConnected()) { + if (ref != null) { + updateText(ref); + if (ref instanceof HostRef) { + showPage(mainScrollPage); + } else { + showPage(vmPage); + } + } + } else { + showPage(notConnectedPage); + } + } + } + }; + + private void showPage(final Control page) { + PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + if (page instanceof ScrolledComposite) { + ((ScrolledComposite) page).getContent().pack(); + } else { + page.pack(); + } + pageBook.showPage(page); + } + }); + } + + @Override + public void createPartControl(Composite parent) { + pageBook = new PageBook(parent, SWT.NONE); + mainScrollPage = new ScrolledComposite(pageBook, SWT.NONE + | SWT.V_SCROLL | SWT.H_SCROLL); + Composite main = new Composite(mainScrollPage, SWT.NONE); + mainScrollPage.setContent(main); + vmPage = new Composite(pageBook, SWT.NONE); + + vmName = new Label(vmPage, SWT.NONE); + vmPage.setLayout(new RowLayout()); + + notConnectedPage = new Composite(pageBook, SWT.NONE); + notConnectedPage.setLayout(new RowLayout()); + + // ---------------------------------------- + // Not connected page + // ---------------------------------------- + Label notConn = new Label(notConnectedPage, SWT.NONE); + notConn.setText("Not connected to storage"); + + // ---------------------------------------- + // Main overview page + // ---------------------------------------- + main.setLayout(new GridLayout()); + + // Basics + Label lblBasics = new Label(main, SWT.NONE); + lblBasics.setText("Basics"); // TODO: Externalize + Font stdFont = lblBasics.getFont(); + Font boldFont = new Font(stdFont.getDevice(), + stdFont.getFontData()[0].getName(), + stdFont.getFontData()[0].getHeight(), SWT.BOLD); + lblBasics.setFont(boldFont); + Composite basicsComps = new Composite(main, SWT.NONE); + GridLayout gridlayout = new GridLayout(2, false); + basicsComps.setLayout(gridlayout); + Label lblHostName = new Label(basicsComps, SWT.NONE); + lblHostName.setText("Hostname"); + GridData hostNameGridData = new GridData(SWT.RIGHT, SWT.CENTER, false, + false); + hostNameGridData.widthHint = FIRST_COLUMN_WIDTH; + lblHostName.setLayoutData(hostNameGridData); + hostname = new Label(basicsComps, SWT.NONE); + hostname.setText(STR_UNKNOWN); + hostname.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, true)); + + // Hardware + Label lblHardware = new Label(main, SWT.NONE); + lblHardware.setText("Hardware"); + lblHardware.setFont(boldFont); + Composite hardwareComps = new Composite(main, SWT.NONE); + hardwareComps.setLayout(gridlayout); + Label lblProcModel = new Label(hardwareComps, SWT.NONE); + lblProcModel.setText("Processor Model"); + GridData procModelGridData = new GridData(SWT.RIGHT, SWT.CENTER, false, + false); + procModelGridData.widthHint = FIRST_COLUMN_WIDTH; + lblProcModel.setLayoutData(procModelGridData); + procModel = new Label(hardwareComps, SWT.NONE); + procModel.setText(STR_UNKNOWN); + procModel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, true)); + Label lblProcCount = new Label(hardwareComps, SWT.NONE); + lblProcCount.setText("Processor Count"); + GridData procCountGridData = new GridData(SWT.RIGHT, SWT.CENTER, false, + false); + procCountGridData.widthHint = FIRST_COLUMN_WIDTH; + lblProcCount.setLayoutData(procCountGridData); + procCoreCount = new Label(hardwareComps, SWT.NONE); + procCoreCount.setText(STR_UNKNOWN); + procCoreCount.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, + true)); + Label lblTotalMemory = new Label(hardwareComps, SWT.NONE); + lblTotalMemory.setText("Total Memory"); + GridData totalMemGridData = new GridData(SWT.RIGHT, SWT.CENTER, false, + false); + totalMemGridData.widthHint = FIRST_COLUMN_WIDTH; + lblTotalMemory.setLayoutData(totalMemGridData); + lblTotalMemory.pack(); + totalMemory = new Label(hardwareComps, SWT.NONE); + totalMemory.setText(STR_UNKNOWN); + totalMemory + .setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, true)); + Label lblNetwork = new Label(hardwareComps, SWT.NONE); + lblNetwork.setText("Network"); + GridData networkLayout = new GridData(SWT.RIGHT, SWT.TOP, true, true); + networkLayout.widthHint = FIRST_COLUMN_WIDTH; + lblNetwork.setLayoutData(networkLayout); + networkInterfaces = new TableViewer(hardwareComps, SWT.BORDER); + createNetworkTableViewer(networkInterfaces); + + // Software + Label lblSoftware = new Label(main, SWT.NONE); + lblSoftware.setText("Software"); + lblSoftware.setFont(boldFont); + Composite softwareComps = new Composite(main, SWT.NONE); + softwareComps.setLayout(gridlayout); + Label lblOsName = new Label(softwareComps, SWT.NONE); + lblOsName.setText("OS Name"); + GridData osNameGridData = new GridData(SWT.RIGHT, SWT.CENTER, false, + false); + osNameGridData.widthHint = FIRST_COLUMN_WIDTH; + lblOsName.setLayoutData(osNameGridData); + osName = new Label(softwareComps, SWT.NONE); + osName.setText(STR_UNKNOWN); + osName.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, true)); + Label lblKernel = new Label(softwareComps, SWT.NONE); + lblKernel.setText("OS Kernel"); + GridData osKernelGridData = new GridData(SWT.RIGHT, SWT.CENTER, false, + false); + osKernelGridData.widthHint = FIRST_COLUMN_WIDTH; + lblKernel.setLayoutData(osKernelGridData); + osKernel = new Label(softwareComps, SWT.NONE); + osKernel.setText(STR_UNKNOWN); + osKernel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, true)); + + // Listen for VMtree changes + getSite().getWorkbenchWindow().getSelectionService() + .addSelectionListener(listener); + if (Activator.getDefault().isConnected()) { + ISelection selection = getSite().getWorkbenchWindow() + .getSelectionService().getSelection(); + Ref ref = getRefFromSelection(selection); + if (ref != null) { + updateText(ref); + if (ref instanceof HostRef) { + showPage(mainScrollPage); + } else { + showPage(vmPage); + } + } else { + // FIXME: probably want to show something else, e.g. select x in + // VM tree + showPage(notConnectedPage); + } + } else { + showPage(notConnectedPage); + } + } + + @Override + public void setFocus() { + pageBook.setFocus(); + } + + private void updateText(Ref ref) { + if (ref instanceof HostRef) { + updateText((HostRef) ref); + } else { + updateText((VmRef) ref); + } + } + + private void updateText(final HostRef hostRef) { + DAOFactory df = ApplicationContext.getInstance().getDAOFactory(); + HostInfoDAO hostInfoDAO = df.getHostInfoDAO(); + final HostInfo hostInfo = hostInfoDAO.getHostInfo(hostRef); + final NetworkInterfaceInfoDAO networkInfoDAO = df + .getNetworkInterfaceInfoDAO(); + PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + hostname.setText(hostRef.getHostName()); + osName.setText(hostInfo.getOsName()); + procModel.setText(hostInfo.getCpuModel()); + procCoreCount.setText(Integer.toString(hostInfo.getCpuCount())); + osKernel.setText(hostInfo.getOsKernel()); + totalMemory.setText(Long.toString(hostInfo.getTotalMemory())); + // set content for the network iface table + networkInterfaces.setInput(networkInfoDAO.getNetworkInterfaces( + hostRef).toArray()); + } + }); + } + + private void updateText(final VmRef vmRef) { + PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + vmName.setText(vmRef.getName()); + } + }); + } + + private Ref getRefFromSelection(ISelection selection) { + if (selection instanceof IStructuredSelection) { + IStructuredSelection ss = (IStructuredSelection) selection; + // FIXME: hostsVms tree should only allow single selections + for (Object item : ss.toArray()) { + if (item instanceof Ref) { + return (Ref) item; + } + } + } + return null; + } + + @Override + public void dispose() { + // important: We need do unregister our listener when the view is + // disposed + getSite().getWorkbenchWindow().getSelectionService() + .removeSelectionListener(listener); + super.dispose(); + } + + private void createNetworkTableViewer(TableViewer viewer) { + createColumns(viewer.getControl().getParent(), viewer); + final Table table = viewer.getTable(); + table.setHeaderVisible(true); + table.setLinesVisible(true); + + viewer.setContentProvider(new ArrayContentProvider()); + // create empty table + viewer.setInput(new Object[0]); + } + + // This will create the columns for the table + private void createColumns(final Composite parent, final TableViewer viewer) { + String[] titles = { "Interface", "IPv4 Address", "IPv6 Address" }; + int[] bounds = { 80, 150, 150 }; + + // First column is iface name + TableViewerColumn col = createTableViewerColumn(viewer, titles[0], + bounds[0], 0); + col.setLabelProvider(new ColumnLabelProvider() { + @Override + public String getText(Object element) { + NetworkInterfaceInfo iface = (NetworkInterfaceInfo) element; + return iface.getInterfaceName(); + } + }); + + // Second column is IPv4 + col = createTableViewerColumn(viewer, titles[1], bounds[1], 1); + col.setLabelProvider(new ColumnLabelProvider() { + @Override + public String getText(Object element) { + NetworkInterfaceInfo iface = (NetworkInterfaceInfo) element; + return iface.getIp4Addr(); + } + }); + + // IPv6 + col = createTableViewerColumn(viewer, titles[2], bounds[2], 2); + col.setLabelProvider(new ColumnLabelProvider() { + @Override + public String getText(Object element) { + NetworkInterfaceInfo iface = (NetworkInterfaceInfo) element; + return iface.getIp6Addr(); + } + }); + } + + private TableViewerColumn createTableViewerColumn(TableViewer viewer, + String title, int bound, final int colNumber) { + final TableViewerColumn viewerColumn = new TableViewerColumn(viewer, + SWT.NONE); + final TableColumn column = viewerColumn.getColumn(); + column.setText(title); + column.setWidth(bound); + column.setResizable(true); + column.setMoveable(false); + return viewerColumn; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/eclipse/com.redhat.thermostat.eclipse/src/com/redhat/thermostat/eclipse/views/HostsVmsTreeViewPart.java Fri Aug 17 15:34:32 2012 +0200 @@ -0,0 +1,289 @@ +/* + * Copyright 2012 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.eclipse.views; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.IJobChangeEvent; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.core.runtime.jobs.JobChangeAdapter; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Link; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.part.PageBook; +import org.eclipse.ui.part.ViewPart; + +import com.redhat.thermostat.common.DefaultHostsVMsLoader; +import com.redhat.thermostat.common.HostsVMsLoader; +import com.redhat.thermostat.common.ThreadPoolTimerFactory; +import com.redhat.thermostat.common.TimerFactory; +import com.redhat.thermostat.common.appctx.ApplicationContext; +import com.redhat.thermostat.common.config.InvalidConfigurationException; +import com.redhat.thermostat.common.dao.DAOFactory; +import com.redhat.thermostat.common.dao.HostInfoDAO; +import com.redhat.thermostat.common.dao.MongoDAOFactory; +import com.redhat.thermostat.common.dao.VmInfoDAO; +import com.redhat.thermostat.common.storage.Connection; +import com.redhat.thermostat.common.storage.Connection.ConnectionListener; +import com.redhat.thermostat.common.storage.Connection.ConnectionStatus; +import com.redhat.thermostat.common.storage.ConnectionException; +import com.redhat.thermostat.common.storage.MongoStorageProvider; +import com.redhat.thermostat.common.storage.StorageProvider; +import com.redhat.thermostat.eclipse.Activator; +import com.redhat.thermostat.eclipse.ConnectionConfiguration; +import com.redhat.thermostat.eclipse.LoggerFacility; +import com.redhat.thermostat.eclipse.model.HostsVmsLabelProvider; +import com.redhat.thermostat.eclipse.model.HostsVmsTreeContentProvider; +import com.redhat.thermostat.eclipse.model.HostsVmsTreeRoot; + +/** + * + * The main class for the VM tree view of the Thermostat Eclipse client. + * + */ +public class HostsVmsTreeViewPart extends ViewPart { + + private Action connectAction; + // Hosts and VMs viewer + private TreeViewer treeViewer; + // viewer for the connect viewing. + private Composite connectPage; + // Container for tree and connect + private PageBook pageBook; + + private ConnectionConfiguration configuration; + + private void showConnectionPage() { + PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + pageBook.showPage(connectPage); + } + }); + } + + private void showHostVmsPage() { + HostInfoDAO hostDAO = ApplicationContext.getInstance().getDAOFactory() + .getHostInfoDAO(); + VmInfoDAO vmsDAO = ApplicationContext.getInstance().getDAOFactory() + .getVmInfoDAO(); + final HostsVMsLoader loader = new DefaultHostsVMsLoader(hostDAO, + vmsDAO, false); + + PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + treeViewer.setContentProvider(new HostsVmsTreeContentProvider( + loader)); + treeViewer.setLabelProvider(new HostsVmsLabelProvider()); + treeViewer.setUseHashlookup(true); + treeViewer.setInput(new HostsVmsTreeRoot()); + pageBook.showPage(treeViewer.getControl()); + } + + }); + } + + @Override + public void createPartControl(final Composite parent) { + connectAction = new Action("Connect to storage...") { + public void run() { + Job connectJob = new ConnectJob( + "Connecting to Thermostat storage..."); + connectJob.setSystem(true); + connectJob.addJobChangeListener(new ConnectionJobListener()); + connectJob.schedule(); + } + }; + connectAction.setImageDescriptor(Activator + .getImageDescriptor("icons/offline.png")); + IToolBarManager mgr = getViewSite().getActionBars().getToolBarManager(); + mgr.add(connectAction); + + configuration = new ConnectionConfiguration("mongodb://127.0.0.1:27518"); + pageBook = new PageBook(parent, SWT.NONE); + + // Prepare Hosts/VMs tree + treeViewer = new TreeViewer(pageBook, SWT.NONE); + // register the tree as selection provider + getSite().setSelectionProvider(treeViewer); + + // Prepare connect page + RowLayout layout = new RowLayout(); + layout.wrap = true; + connectPage = new Composite(pageBook, SWT.NONE); + connectPage.setLayout(layout); + Label test = new Label(connectPage, SWT.NONE); + test.setText("Not connected... "); + Link link = new Link(connectPage, SWT.NONE); + // FIXME: Externalize + link.setText("<a>Connect</a>"); + link.addListener(SWT.Selection, new Listener() { + @Override + public void handleEvent(Event event) { + // implement connect + Job connectJob = new ConnectJob( + "Connecting to Thermostat storage..."); + connectJob.setSystem(true); + connectJob.addJobChangeListener(new ConnectionJobListener()); + connectJob.schedule(); + } + }); + // Show appropriate page + boolean connected = Activator.getDefault().isConnected(); + if (connected) { + showHostVmsPage(); + } else { + showConnectionPage(); + } + } + + @Override + public void setFocus() { + pageBook.setFocus(); + } + + /* + * Mongo connection method + */ + private boolean connectToBackEnd() throws InvalidConfigurationException { + StorageProvider connProv = new MongoStorageProvider(configuration); + DAOFactory daoFactory = new MongoDAOFactory(connProv); + ApplicationContext.getInstance().setDAOFactory(daoFactory); + TimerFactory timerFactory = new ThreadPoolTimerFactory(1); + ApplicationContext.getInstance().setTimerFactory(timerFactory); + + Connection connection = daoFactory.getConnection(); + ConnectionListener connectionListener = new ConnectionListener() { + @Override + public void changed(ConnectionStatus newStatus) { + switch (newStatus) { + case DISCONNECTED: + LoggerFacility.getInstance().log(IStatus.WARNING, + "Unexpected disconnect event."); + break; + case CONNECTING: + LoggerFacility.getInstance().log(IStatus.INFO, + "Connecting to storage."); + break; + case CONNECTED: + LoggerFacility.getInstance().log(IStatus.INFO, + "Connected to storage."); + Activator.getDefault().setConnected(true); + break; + case FAILED_TO_CONNECT: + LoggerFacility.getInstance().log(IStatus.WARNING, + "Could not connect to storage."); + default: + LoggerFacility.getInstance().log(IStatus.WARNING, + "Unfamiliar ConnectionStatus value"); + } + } + }; + connection.addListener(connectionListener); + try { + LoggerFacility.getInstance().log(IStatus.INFO, + "Connecting to storage..."); + connection.connect(); + return true; + } catch (final ConnectionException e) { + LoggerFacility.getInstance().log(IStatus.ERROR, + e.getCause().getMessage(), e.getCause()); + PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + // FIXME: Show a nicer error message + MessageDialog.openError(null, "Connection Problem", e + .getCause().getMessage()); + } + + }); + return false; + } + } + + private class ConnectJob extends Job { + + public ConnectJob(String name) { + super(name); + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + monitor.beginTask( + "Connecting to " + configuration.getDBConnectionString(), + IProgressMonitor.UNKNOWN); + try { + if (connectToBackEnd()) { + return Status.OK_STATUS; + } + } catch (InvalidConfigurationException e) { + // FIXME: do something more reasonable + } + return Status.CANCEL_STATUS; + } + + } + + private class ConnectionJobListener extends JobChangeAdapter { + + @Override + public void done(IJobChangeEvent event) { + IStatus result = event.getResult(); + if (result.isOK() && result.getCode() != IStatus.CANCEL) { + showHostVmsPage(); + connectAction.setImageDescriptor(Activator + .getImageDescriptor("icons/online.png")); + connectAction.setEnabled(!Activator.getDefault().isConnected()); + connectAction.setToolTipText("Online"); + } + } + + } + +}
--- a/client/eclipse/pom.xml Fri Aug 17 13:13:47 2012 +0200 +++ b/client/eclipse/pom.xml Fri Aug 17 15:34:32 2012 +0200 @@ -36,17 +36,7 @@ <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0</modelVersion> - - <parent> - <groupId>org.eclipse</groupId> - <artifactId>eclipse-parent</artifactId> - <version>3</version> - </parent> - - <prerequisites> - <maven>3.0</maven> - </prerequisites> - + <groupId>com.redhat.thermostat.eclipse.parent</groupId> <artifactId>thermostat-eclipse-parent</artifactId> <version>0.4.0-SNAPSHOT</version> @@ -65,7 +55,7 @@ <tycho-extras-version>0.15.0</tycho-extras-version> <platform-version-name>juno</platform-version-name> <eclipse-site>http://download.eclipse.org/releases/${platform-version-name}</eclipse-site> - <orbit-site>http://download.eclipse.org/tools/orbit/downloads/drops/R20110523182458/repository/</orbit-site> + <orbit-site>http://download.eclipse.org/tools/orbit/downloads/drops/S20120726065500/repository/</orbit-site> </properties> <profiles> @@ -100,6 +90,8 @@ <modules> <module>com.redhat.thermostat.eclipse.boot</module> + <module>com.redhat.thermostat.eclipse</module> + <module>com.redhat.thermostat.eclipse.test</module> </modules> <repositories> @@ -133,6 +125,8 @@ <version>${tycho-version}</version> <configuration> <resolver>p2</resolver> + <!-- required for Thermostat core deps resolution --> + <pomDependencies>consider</pomDependencies> </configuration> </plugin> <plugin> @@ -167,17 +161,24 @@ <configuration> <encoding>UTF-8</encoding> </configuration> - </plugin> - <plugin> - <groupId>org.eclipse.tycho</groupId> - <artifactId>tycho-surefire-plugin</artifactId> - <version>${tycho-version}</version> - <configuration> - <useUIHarness>true</useUIHarness> - <useUIThread>true</useUIThread> - <product>org.eclipse.sdk.ide</product> - </configuration> - </plugin> + </plugin> + <plugin> + <groupId>org.eclipse.tycho</groupId> + <artifactId>tycho-surefire-plugin</artifactId> + <version>${tycho-version}</version> + <configuration> + <useUIHarness>false</useUIHarness> + <useUIThread>flase</useUIThread> + <dependencies> + <dependency> + <type>p2-installable-unit</type> + <artifactId>org.eclipse.sdk.feature.group</artifactId> + <version>${sdk-version}</version> + </dependency> + </dependencies> + <product>org.eclipse.sdk.ide</product> + </configuration> + </plugin> <plugin> <!-- TODO remove workaround when https://issues.sonatype.org/browse/TYCHO-473