Mercurial > hg > thermostat-ng > agent
changeset 2680:8babf77875ec
Move GC plugin to Declarative Services
Reviewed-by: jkang
Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2017-May/023387.html
line wrap: on
line diff
--- a/agent/core/src/main/java/com/redhat/thermostat/backend/BaseBackend.java Wed May 31 12:06:16 2017 -0400 +++ b/agent/core/src/main/java/com/redhat/thermostat/backend/BaseBackend.java Fri Jun 02 11:29:26 2017 -0400 @@ -44,15 +44,14 @@ private String name, description, vendor, version; - public BaseBackend(String name, String description, String vendor, String version) { - this(name, description, vendor, version, false); + public BaseBackend(String name, String description, String vendor) { + this(name, description, vendor, false); } - public BaseBackend(String name, String description, String vendor, String version, boolean observeNewJvm) { + public BaseBackend(String name, String description, String vendor, boolean observeNewJvm) { this.name = Objects.requireNonNull(name); this.description = Objects.requireNonNull(description); this.vendor = Objects.requireNonNull(vendor); - this.version = Objects.requireNonNull(version); this.observeNewJvm = observeNewJvm; } @@ -75,6 +74,15 @@ public String getVersion() { return version; } + + /** + * Sets version number of this {@link Backend}. Subclasses should + * call this method prior to registering this Backend. + * @param version version number of this Backend + */ + protected void setVersion(String version) { + this.version = version; + } @Override public boolean getObserveNewJvm() {
--- a/agent/core/src/main/java/com/redhat/thermostat/backend/PollingBackend.java Wed May 31 12:06:16 2017 -0400 +++ b/agent/core/src/main/java/com/redhat/thermostat/backend/PollingBackend.java Fri Jun 02 11:29:26 2017 -0400 @@ -61,9 +61,9 @@ PollingBackend(String name, String description, String vendor, Version version, ScheduledExecutorService executor) { - super(name, description, vendor, - version.getVersionNumber(), true); + super(name, description, vendor, true); this.executor = executor; + setVersion(version.getVersionNumber()); } @Override
--- a/agent/core/src/main/java/com/redhat/thermostat/backend/VmListenerBackend.java Wed May 31 12:06:16 2017 -0400 +++ b/agent/core/src/main/java/com/redhat/thermostat/backend/VmListenerBackend.java Fri Jun 02 11:29:26 2017 -0400 @@ -59,22 +59,18 @@ private static final Logger logger = LoggingUtils.getLogger(VmListenerBackend.class); - private final VmStatusListenerRegistrar registrar; - private final WriterID writerId; + private WriterID writerId; + private VmStatusListenerRegistrar registrar; private VmMonitor monitor; private boolean started; + private boolean initialized; - public VmListenerBackend(String backendName, String description, - String vendor, String version, VmStatusListenerRegistrar registrar, - WriterID writerId) { - this(backendName, description, vendor, version, false, registrar, writerId); + public VmListenerBackend(String backendName, String description, String vendor) { + this(backendName, description, vendor, false); } public VmListenerBackend(String backendName, String description, - String vendor, String version, boolean observeNewJvm, - VmStatusListenerRegistrar registrar, WriterID writerId) { - super(backendName, description, vendor, version, observeNewJvm); - this.registrar = registrar; - this.writerId = writerId; + String vendor, boolean observeNewJvm) { + super(backendName, description, vendor, observeNewJvm); try { this.monitor = new VmMonitor(); } catch (BackendException e) { @@ -89,16 +85,22 @@ * Registers a VmUpdateListener to begin receiving VM lifecycle events. * Subclasses should call <code>super.activate()</code> when overriding this method. * </p> + * <p> + * This {@link VmListenerBackend} should be initialized via + * {@link #initialize(WriterID, VmStatusListenerRegistrar)} before calling this method. + * </p> */ @Override public boolean activate() { - if (!started && monitor != null) { + if (!initialized) { + logger.warning("Backend not started, initialize must be called before activate"); + } else if (!started && monitor != null) { registrar.register(this); started = true; } return started; } - + /** * {@inheritDoc} * @@ -151,6 +153,20 @@ } /** + * Initializes this {@link VmListenerBackend} with necessary services. This method + * must be called before {@link #activate()}. + * @param writerId service uniquely identifying this agent + * @param registrar responsible for registering and unregistering instances of {@link VmStatusListener} + * @param version version number of this backend + */ + protected void initialize(WriterID writerId, VmStatusListenerRegistrar registrar, String version) { + this.writerId = writerId; + this.registrar = registrar; + setVersion(version); + this.initialized = true; + } + + /** * Creates a new {@link VmUpdateListener} for the virtual machine * specified by the pid. This method is called when a new * JVM is started or for JVMs already active when this Backend
--- a/agent/core/src/test/java/com/redhat/thermostat/backend/BaseBackendTest.java Wed May 31 12:06:16 2017 -0400 +++ b/agent/core/src/test/java/com/redhat/thermostat/backend/BaseBackendTest.java Fri Jun 02 11:29:26 2017 -0400 @@ -58,11 +58,6 @@ } @Test(expected = NullPointerException.class) - public void testConstructorRejectsNullVersion() { - new TestBaseBackend("", "", "", null); - } - - @Test(expected = NullPointerException.class) public void testConstructorRejectsNullDescription() { new TestBaseBackend("", null, "", ""); } @@ -139,12 +134,14 @@ public TestBaseBackend(String name, String description, String vendor, String version) { - super(name, description, vendor, version); + super(name, description, vendor); + setVersion(version); } public TestBaseBackend(String name, String description, String vendor, String version, boolean observeNewJvm) { - super(name, description, vendor, version, observeNewJvm); + super(name, description, vendor, observeNewJvm); + setVersion(version); } @Override
--- a/agent/core/src/test/java/com/redhat/thermostat/backend/VmListenerBackendTest.java Wed May 31 12:06:16 2017 -0400 +++ b/agent/core/src/test/java/com/redhat/thermostat/backend/VmListenerBackendTest.java Fri Jun 02 11:29:26 2017 -0400 @@ -41,6 +41,7 @@ import static org.mockito.Matchers.any; import static org.mockito.Matchers.same; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -58,6 +59,7 @@ import com.redhat.thermostat.storage.core.WriterID; public class VmListenerBackendTest { + private static final String VERSION = "0.0.0"; private static final String VM_ID = "vmId"; private static final int VM_PID = 1; @@ -65,13 +67,13 @@ private VmStatusListenerRegistrar registrar; private VmMonitor monitor; private VmUpdateListener listener; + private WriterID writerId; @Before public void setup() { registrar = mock(VmStatusListenerRegistrar.class); - WriterID id = mock(WriterID.class); - backend = new TestBackend("Test Backend", "Backend for test", "Test Co.", - "0.0.0", registrar, id); + writerId = mock(WriterID.class); + backend = new TestBackend("Test Backend", "Backend for test", "Test Co."); monitor = mock(VmMonitor.class); listener = mock(VmUpdateListener.class); backend.setMonitor(monitor); @@ -79,13 +81,22 @@ @Test public void testActivate() { + backend.initialize(writerId, registrar, VERSION); backend.activate(); assertTrue(backend.isActive()); verify(registrar).register(backend); } + + @Test + public void testActivateNoInit() { + backend.activate(); + assertFalse(backend.isActive()); + verify(registrar, never()).register(backend); + } @Test public void testActivateTwice() { + backend.initialize(writerId, registrar, VERSION); assertTrue(backend.activate()); assertTrue(backend.isActive()); @@ -95,6 +106,7 @@ @Test public void testCanNotActivateWithoutMonitor() { + backend.initialize(writerId, registrar, VERSION); backend.setMonitor(null); assertFalse(backend.activate()); @@ -103,6 +115,7 @@ @Test public void testDeactivate() { + backend.initialize(writerId, registrar, VERSION); backend.activate(); backend.deactivate(); verify(registrar).unregister(backend); @@ -111,6 +124,7 @@ @Test public void testDeactivateTwice() { + backend.initialize(writerId, registrar, VERSION); backend.activate(); assertTrue(backend.deactivate()); @@ -120,6 +134,7 @@ @Test public void testNewVM() { + backend.initialize(writerId, registrar, VERSION); // Should be no response if not observing new jvm. backend.setObserveNewJvm(false); backend.vmStatusChanged(Status.VM_STARTED, VM_ID, VM_PID); @@ -141,11 +156,9 @@ url = "http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=3242") @Test public void testNewVMCreateListenerWithExceptions() { - VmStatusListenerRegistrar customRegistrar = mock(VmStatusListenerRegistrar.class); - WriterID wid = mock(WriterID.class); VmListenerBackend testBackend = new ExceptionThrowingCreateVmListenerBackend( - "Test Backend", "Backend for test", "Test Co.", - "0.0.0", customRegistrar, wid); + "Test Backend", "Backend for test", "Test Co.", VERSION); + testBackend.initialize(writerId, registrar, VERSION); testBackend.setObserveNewJvm(true); VmMonitor testMonitor = mock(VmMonitor.class); testBackend.setMonitor(testMonitor); @@ -155,6 +168,7 @@ @Test public void testAlreadyRunningVM() { + backend.initialize(writerId, registrar, VERSION); backend.setObserveNewJvm(true); backend.vmStatusChanged(Status.VM_ACTIVE, VM_ID, VM_PID); @@ -163,6 +177,7 @@ @Test public void testStoppedVM() throws MonitorException, URISyntaxException { + backend.initialize(writerId, registrar, VERSION); backend.setObserveNewJvm(true); backend.vmStatusChanged(Status.VM_STARTED, VM_ID, VM_PID); backend.vmStatusChanged(Status.VM_STOPPED, VM_ID, VM_PID); @@ -172,6 +187,7 @@ @Test public void testDeactivateUnregistersListener() throws URISyntaxException, MonitorException { + backend.initialize(writerId, registrar, VERSION); backend.activate(); backend.setObserveNewJvm(true); @@ -182,9 +198,8 @@ private class TestBackend extends VmListenerBackend { - public TestBackend(String name, String description, String vendor, - String version, VmStatusListenerRegistrar registrar, WriterID writerId) { - super(name, description, vendor, version, registrar, writerId); + public TestBackend(String name, String description, String vendor) { + super(name, description, vendor); } @Override @@ -202,8 +217,8 @@ private class ExceptionThrowingCreateVmListenerBackend extends TestBackend { public ExceptionThrowingCreateVmListenerBackend(String name, String description, String vendor, - String version, VmStatusListenerRegistrar registrar, WriterID writerId) { - super(name, description, vendor, version, registrar, writerId); + String version) { + super(name, description, vendor); } @Override
--- a/plugins/host-overview/agent/src/main/java/com/redhat/thermostat/host/overview/internal/HostOverviewBackend.java Wed May 31 12:06:16 2017 -0400 +++ b/plugins/host-overview/agent/src/main/java/com/redhat/thermostat/host/overview/internal/HostOverviewBackend.java Fri Jun 02 11:29:26 2017 -0400 @@ -42,7 +42,7 @@ import org.apache.felix.scr.annotations.Deactivate; import org.apache.felix.scr.annotations.Reference; import org.apache.felix.scr.annotations.Service; -import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.BundleContext; import com.redhat.thermostat.backend.Backend; import com.redhat.thermostat.backend.BaseBackend; @@ -60,24 +60,17 @@ @Reference private HostInfoDAO hostInfoDAO; - @Reference private WriterID writerID; private boolean started; public HostOverviewBackend() { - this(new Version(FrameworkUtil.getBundle(HostOverviewBackend.class)), null, null, new HostInfoBuilderCreator()); + this(new HostInfoBuilderCreator()); } - HostOverviewBackend(Version version, HostInfoDAO hostInfoDAO, WriterID writerID, - HostInfoBuilderCreator builderCreator) { - super("Host Overview Backend", - "Gathers general information about a host", - "Red Hat, Inc.", - version.getVersionNumber()); - this.hostInfoDAO = hostInfoDAO; - this.writerID = writerID; + HostOverviewBackend(HostInfoBuilderCreator builderCreator) { + super("Host Overview Backend", "Gathers general information about a host", "Red Hat, Inc."); this.builderCreator = builderCreator; } @@ -114,12 +107,26 @@ } @Activate + protected void componentActivated(BundleContext context) { + Version version = new Version(context.getBundle()); + setVersion(version.getVersionNumber()); + } + @Deactivate - protected void noop() { - /* Map unused DS activate/deactivate methods to this NOOP method to - * prevent it from trying to use Backend.activate/deactivate and - * giving an error about them being incompatible. - */ + protected void componentDeactivated() { + if (isActive()) { + deactivate(); + } + } + + // DS bind method + protected void bindHostInfoDAO(HostInfoDAO dao) { + this.hostInfoDAO = dao; + } + + // DS bind method + protected void bindWriterID(WriterID id) { + this.writerID = id; } }
--- a/plugins/host-overview/agent/src/test/java/com/redhat/thermostat/host/overview/internal/HostOverviewBackendTest.java Wed May 31 12:06:16 2017 -0400 +++ b/plugins/host-overview/agent/src/test/java/com/redhat/thermostat/host/overview/internal/HostOverviewBackendTest.java Fri Jun 02 11:29:26 2017 -0400 @@ -36,6 +36,7 @@ package com.redhat.thermostat.host.overview.internal; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; @@ -44,8 +45,10 @@ import org.junit.Before; import org.junit.Test; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.Version; -import com.redhat.thermostat.common.Version; import com.redhat.thermostat.host.overview.internal.models.HostInfoBuilder; import com.redhat.thermostat.host.overview.internal.models.HostInfoDAO; import com.redhat.thermostat.host.overview.model.HostInfo; @@ -63,8 +66,6 @@ @Before public void setup() { hostInfoDAO = mock(HostInfoDAO.class); - Version version = mock(Version.class); - when(version.getVersionNumber()).thenReturn("0.0.0"); writerID = mock(WriterID.class); info = mock(HostInfo.class); @@ -73,7 +74,9 @@ builderCreator = mock(HostOverviewBackend.HostInfoBuilderCreator.class); when(builderCreator.create(writerID)).thenReturn(builder); - backend = new HostOverviewBackend(version, hostInfoDAO, writerID, builderCreator); + backend = new HostOverviewBackend(builderCreator); + backend.bindHostInfoDAO(hostInfoDAO); + backend.bindWriterID(writerID); } @Test @@ -92,5 +95,26 @@ backend.deactivate(); assertFalse(backend.isActive()); } + + @Test + public void testComponentActivated() { + BundleContext context = mock(BundleContext.class); + Bundle bundle = mock(Bundle.class); + Version version = new Version(1, 2, 3); + when(bundle.getVersion()).thenReturn(version); + when(context.getBundle()).thenReturn(bundle); + + backend.componentActivated(context); + + assertEquals("1.2.3", backend.getVersion()); + } + + @Test + public void testComponentDeactivated() { + backend.activate(); + assertTrue(backend.isActive()); + backend.componentDeactivated(); + assertFalse(backend.isActive()); + } }
--- a/plugins/vm-gc/agent/pom.xml Wed May 31 12:06:16 2017 -0400 +++ b/plugins/vm-gc/agent/pom.xml Fri Jun 02 11:29:26 2017 -0400 @@ -56,7 +56,6 @@ <instructions> <Bundle-Vendor>Red Hat, Inc.</Bundle-Vendor> <Bundle-SymbolicName>com.redhat.thermostat.vm.gc.agent</Bundle-SymbolicName> - <Bundle-Activator>com.redhat.thermostat.vm.gc.agent.internal.Activator</Bundle-Activator> <Export-Package /> <Private-Package> com.redhat.thermostat.vm.gc.agent.internal @@ -66,6 +65,18 @@ </instructions> </configuration> </plugin> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-scr-plugin</artifactId> + <executions> + <execution> + <id>generate-scr-scrdescriptor</id> + <goals> + <goal>scr</goal> + </goals> + </execution> + </executions> + </plugin> </plugins> </build> <dependencies>
--- a/plugins/vm-gc/agent/src/main/java/com/redhat/thermostat/vm/gc/agent/internal/Activator.java Wed May 31 12:06:16 2017 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,104 +0,0 @@ -/* - * Copyright 2012-2017 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.gc.agent.internal; - -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.MultipleServiceTracker.Action; -import com.redhat.thermostat.common.MultipleServiceTracker.DependencyProvider; -import com.redhat.thermostat.common.Version; -import com.redhat.thermostat.storage.core.WriterID; -import com.redhat.thermostat.vm.gc.common.VmGcStatDAO; - -public class Activator implements BundleActivator { - - private MultipleServiceTracker tracker; - private VmGcBackend backend; - private ServiceRegistration<Backend> reg; - - @Override - public void start(final BundleContext context) throws Exception { - Class<?>[] deps = new Class<?>[] { - BackendService.class, - VmGcStatDAO.class, - WriterID.class, // vm gc backend uses it. - }; - - final VmStatusListenerRegistrar registerer = new VmStatusListenerRegistrar(context); - - tracker = new MultipleServiceTracker(context, deps, new Action() { - - @Override - public void dependenciesAvailable(DependencyProvider services) { - VmGcStatDAO vmGcStatDao = services.get(VmGcStatDAO.class); - Version version = new Version(context.getBundle()); - WriterID writerId = services.get(WriterID.class); - backend = new VmGcBackend(vmGcStatDao, version, registerer, writerId); - reg = context.registerService(Backend.class, backend, null); - } - - @Override - public void dependenciesUnavailable() { - if (backend.isActive()) { - backend.deactivate(); - } - reg.unregister(); - } - - }); - tracker.open(); - } - - @Override - public void stop(BundleContext context) throws Exception { - tracker.close(); - } - - /* - * For testing purposes only. - */ - VmGcBackend getBackend() { - return backend; - } -} -
--- a/plugins/vm-gc/agent/src/main/java/com/redhat/thermostat/vm/gc/agent/internal/VmGcBackend.java Wed May 31 12:06:16 2017 -0400 +++ b/plugins/vm-gc/agent/src/main/java/com/redhat/thermostat/vm/gc/agent/internal/VmGcBackend.java Fri Jun 02 11:29:26 2017 -0400 @@ -36,7 +36,15 @@ package com.redhat.thermostat.vm.gc.agent.internal; +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.Service; +import org.osgi.framework.BundleContext; + import com.redhat.thermostat.agent.VmStatusListenerRegistrar; +import com.redhat.thermostat.backend.Backend; import com.redhat.thermostat.backend.VmListenerBackend; import com.redhat.thermostat.backend.VmUpdateListener; import com.redhat.thermostat.common.Version; @@ -44,16 +52,24 @@ import com.redhat.thermostat.vm.gc.common.Constants; import com.redhat.thermostat.vm.gc.common.VmGcStatDAO; +@Component +@Service(value = Backend.class) public class VmGcBackend extends VmListenerBackend { - private final VmGcStatDAO vmGcStats; - - public VmGcBackend(VmGcStatDAO vmGcStatDAO, Version version, - VmStatusListenerRegistrar registrar, WriterID writerId) { - super("VM GC Backend", - "Gathers garbage collection statistics about a JVM", - "Red Hat, Inc.", version.getVersionNumber(), true, registrar, writerId); - this.vmGcStats = vmGcStatDAO; + private final ListenerCreator listenerCreator; + + @Reference + private VmGcStatDAO vmGcStats; + @Reference + private WriterID writerId; + + public VmGcBackend() { + this(new ListenerCreator()); + } + + VmGcBackend(ListenerCreator creator) { + super("VM GC Backend", "Gathers garbage collection statistics about a JVM", "Red Hat, Inc.", true); + this.listenerCreator = creator; } @Override @@ -63,8 +79,39 @@ @Override protected VmUpdateListener createVmListener(String writerId, String vmId, int pid) { - return new VmGcVmListener(writerId, vmGcStats, vmId); + return listenerCreator.create(writerId, vmGcStats, vmId); } + @Activate + protected void componentActivated(BundleContext context) { + VmStatusListenerRegistrar registrar = new VmStatusListenerRegistrar(context); + Version version = new Version(context.getBundle()); + initialize(writerId, registrar, version.getVersionNumber()); + } + + @Deactivate + protected void componentDeactivated() { + if (isActive()) { + deactivate(); + } + } + + // DS bind method + protected void bindVmGcStats(VmGcStatDAO dao) { + this.vmGcStats = dao; + } + + // DS bind method + protected void bindWriterId(WriterID id) { + this.writerId = id; + } + + // For testing purposes + static class ListenerCreator { + VmGcVmListener create(String writerId, VmGcStatDAO dao, String vmId) { + return new VmGcVmListener(writerId, dao, vmId); + } + } + }
--- a/plugins/vm-gc/agent/src/test/java/com/redhat/thermostat/vm/gc/agent/internal/ActivatorTest.java Wed May 31 12:06:16 2017 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,108 +0,0 @@ -/* - * Copyright 2012-2017 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.gc.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 org.junit.Test; -import org.osgi.framework.Bundle; -import org.osgi.framework.Version; - -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.gc.common.VmGcStatDAO; - -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); - VmGcStatDAO vmGcStatDAO = mock(VmGcStatDAO.class); - WriterID writerID = mock(WriterID.class); - - context.registerService(BackendService.class, service, null); - context.registerService(VmGcStatDAO.class, vmGcStatDAO, null); - context.registerService(WriterID.class, writerID, null); - - Activator activator = new Activator(); - - activator.start(context); - - assertTrue(context.isServiceRegistered(Backend.class.getName(), VmGcBackend.class)); - VmGcBackend backend = activator.getBackend(); - assertNotNull(backend); - - activator.stop(context); - - assertFalse(backend.isActive()); - - assertEquals(0, context.getServiceListeners().size()); - assertEquals(3, context.getAllServices().size()); - } - -} -
--- a/plugins/vm-gc/agent/src/test/java/com/redhat/thermostat/vm/gc/agent/internal/VmGcBackendTest.java Wed May 31 12:06:16 2017 -0400 +++ b/plugins/vm-gc/agent/src/test/java/com/redhat/thermostat/vm/gc/agent/internal/VmGcBackendTest.java Fri Jun 02 11:29:26 2017 -0400 @@ -36,41 +36,112 @@ package com.redhat.thermostat.vm.gc.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 static org.mockito.Mockito.verify; import org.junit.Before; import org.junit.Test; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.Version; 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.gc.agent.internal.VmGcBackend.ListenerCreator; import com.redhat.thermostat.vm.gc.common.VmGcStatDAO; public class VmGcBackendTest { - private VmGcBackend backend; + private TestVmGcBackend backend; + private ListenerCreator listenerCreator; @Before public void setup() { - VmGcStatDAO vmGcStatDao = mock(VmGcStatDAO.class); - - Version version = mock(Version.class); - when(version.getVersionNumber()).thenReturn("0.0.0"); - - VmStatusListenerRegistrar registrar = mock(VmStatusListenerRegistrar.class); + listenerCreator = mock(ListenerCreator.class); + backend = new TestVmGcBackend(listenerCreator); + } + + @Test + public void testComponentActivated() { + BundleContext context = mock(BundleContext.class); + Bundle bundle = mock(Bundle.class); + Version version = new Version(1, 2, 3); + when(bundle.getVersion()).thenReturn(version); + when(context.getBundle()).thenReturn(bundle); WriterID id = mock(WriterID.class); - backend = new VmGcBackend(vmGcStatDao, version, registrar, id); + backend.bindWriterId(id); + backend.componentActivated(context); + + assertEquals(id, backend.writerId); + assertEquals("1.2.3", backend.version); + assertNotNull(backend.registrar); } - + + @Test + public void testComponentDeactivated() { + // Begin with backend appearing active for this test + backend.active = true; + + assertTrue(backend.isActive()); + backend.componentDeactivated(); + assertFalse(backend.isActive()); + } + + @Test + public void testCreateVmListener() { + final String writerId = "myAgent"; + final String vmId = "myJVM"; + final int pid = 1234; + + VmGcStatDAO dao = mock(VmGcStatDAO.class); + backend.bindVmGcStats(dao); + backend.createVmListener(writerId, vmId, pid); + + verify(listenerCreator).create(writerId, dao, vmId); + } + @Test public void testOrderValue() { int order = backend.getOrderValue(); assertTrue(order >= Ordered.ORDER_MEMORY_GROUP); assertTrue(order < Ordered.ORDER_NETWORK_GROUP); } + + static class TestVmGcBackend extends VmGcBackend { + WriterID writerId; + VmStatusListenerRegistrar registrar; + String version; + boolean active; + + TestVmGcBackend(ListenerCreator creator) { + super(creator); + } + + // Override to capture values + @Override + protected void initialize(WriterID writerId, VmStatusListenerRegistrar registrar, String version) { + this.writerId = writerId; + this.registrar = registrar; + this.version = version; + } + + // Override the following to test backend is deactivated when dependencies are lost + @Override + public boolean isActive() { + return active; + } + @Override + public boolean deactivate() { + active = false; + return true; + } + } }
--- a/plugins/vm-gc/common/pom.xml Wed May 31 12:06:16 2017 -0400 +++ b/plugins/vm-gc/common/pom.xml Fri Jun 02 11:29:26 2017 -0400 @@ -76,7 +76,6 @@ <instructions> <Bundle-Vendor>Red Hat, Inc.</Bundle-Vendor> <Bundle-SymbolicName>com.redhat.thermostat.vm.gc.common</Bundle-SymbolicName> - <Bundle-Activator>com.redhat.thermostat.vm.gc.common.internal.Activator</Bundle-Activator> <Export-Package> com.redhat.thermostat.vm.gc.common, com.redhat.thermostat.vm.gc.common.model, @@ -90,6 +89,18 @@ </instructions> </configuration> </plugin> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-scr-plugin</artifactId> + <executions> + <execution> + <id>generate-scr-scrdescriptor</id> + <goals> + <goal>scr</goal> + </goals> + </execution> + </executions> + </plugin> </plugins> </build> <dependencies> @@ -129,5 +140,10 @@ <version>${project.version}</version> <scope>test</scope> </dependency> + <!-- declarative services --> + <dependency> + <groupId>org.apache.felix</groupId> + <artifactId>org.apache.felix.scr.annotations</artifactId> + </dependency> </dependencies> </project>
--- a/plugins/vm-gc/common/src/main/java/com/redhat/thermostat/vm/gc/common/internal/Activator.java Wed May 31 12:06:16 2017 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,106 +0,0 @@ -/* - * Copyright 2012-2017 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.gc.common.internal; - -import java.util.logging.Level; -import java.util.logging.Logger; - -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.common.config.experimental.ConfigurationInfoSource; -import com.redhat.thermostat.common.utils.LoggingUtils; -import com.redhat.thermostat.vm.gc.common.VmGcStatDAO; - -public class Activator implements BundleActivator { - - private static final Logger logger = LoggingUtils.getLogger(Activator.class); - - private final VmGcStatDAOCreator creator; - private ServiceTracker tracker; - private ServiceRegistration reg; - - public Activator() { - this(new VmGcStatDAOCreator()); - } - - Activator(VmGcStatDAOCreator creator) { - this.creator = creator; - } - - @Override - public void start(BundleContext context) throws Exception { - tracker = new ServiceTracker(context, ConfigurationInfoSource.class.getName(), null) { - @Override - public Object addingService(ServiceReference reference) { - ConfigurationInfoSource source = (ConfigurationInfoSource) super.addingService(reference); - try { - VmGcStatDAO vmGcStatDao = creator.createDAO(new VmGcStatConfiguration(source)); - reg = context.registerService(VmGcStatDAO.class.getName(), vmGcStatDao, null); - } catch (Exception e) { - logger.log(Level.SEVERE, "Failed to create " + VmGcStatDAO.class.getSimpleName(), e); - } - return source; - } - - @Override - public void removedService(ServiceReference reference, Object service) { - if (reg != null) { - reg.unregister(); - } - super.removedService(reference, service); - } - }; - tracker.open(); - } - - @Override - public void stop(BundleContext context) throws Exception { - tracker.close(); - } - - static class VmGcStatDAOCreator { - VmGcStatDAOImpl createDAO(VmGcStatConfiguration config) throws Exception { - return new VmGcStatDAOImpl(config); - } - } - -} -
--- a/plugins/vm-gc/common/src/main/java/com/redhat/thermostat/vm/gc/common/internal/VmGcStatDAOImpl.java Wed May 31 12:06:16 2017 -0400 +++ b/plugins/vm-gc/common/src/main/java/com/redhat/thermostat/vm/gc/common/internal/VmGcStatDAOImpl.java Fri Jun 02 11:29:26 2017 -0400 @@ -44,9 +44,15 @@ import java.util.logging.Level; import java.util.logging.Logger; +import com.redhat.thermostat.common.config.experimental.ConfigurationInfoSource; import com.redhat.thermostat.common.utils.LoggingUtils; import com.redhat.thermostat.vm.gc.common.VmGcStatDAO; import com.redhat.thermostat.vm.gc.common.model.VmGcStat; + +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.Service; import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.api.ContentResponse; import org.eclipse.jetty.client.api.Request; @@ -54,28 +60,42 @@ import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpStatus; +@Component +@Service(value = VmGcStatDAO.class) public class VmGcStatDAOImpl implements VmGcStatDAO { private static final Logger logger = LoggingUtils.getLogger(VmGcStatDAOImpl.class); + static final String CONTENT_TYPE = "application/json"; - private final String gatewayURL; private final JsonHelper jsonHelper; private final HttpHelper httpHelper; private final HttpClient httpClient; - - static final String CONTENT_TYPE = "application/json"; + private final ConfigurationCreator configCreator; + + @Reference + private ConfigurationInfoSource configInfoSource; + private String gatewayURL; - VmGcStatDAOImpl(VmGcStatConfiguration config) throws Exception { - this(config, new HttpClient(), new JsonHelper(new VmGcStatTypeAdapter()), new HttpHelper()); + public VmGcStatDAOImpl() { + this(new HttpClient(), new JsonHelper(new VmGcStatTypeAdapter()), new HttpHelper(), + new ConfigurationCreator(), null); } - VmGcStatDAOImpl(VmGcStatConfiguration config, HttpClient client, JsonHelper jh, HttpHelper hh) throws Exception { - this.gatewayURL = config.getGatewayURL(); + VmGcStatDAOImpl(HttpClient client, JsonHelper jh, HttpHelper hh, ConfigurationCreator creator, + ConfigurationInfoSource source) { this.httpClient = client; this.jsonHelper = jh; this.httpHelper = hh; + this.configCreator = creator; + this.configInfoSource = source; + } - this.httpHelper.startClient(this.httpClient); + @Activate + void activate() throws Exception { + VmGcStatConfiguration config = configCreator.create(configInfoSource); + this.gatewayURL = config.getGatewayURL(); + + httpHelper.startClient(httpClient); } @Override @@ -93,10 +113,6 @@ } } - public Logger getLogger() { - return logger; - } - private void sendRequest(Request httpRequest) throws InterruptedException, TimeoutException, ExecutionException, IOException { ContentResponse resp = httpRequest.send(); @@ -105,7 +121,7 @@ throw new IOException("Gateway returned HTTP status " + String.valueOf(status) + " - " + resp.getReason()); } } - + // For Testing purposes static class JsonHelper { @@ -132,5 +148,14 @@ return new StringContentProvider(content); } } + + // For Testing purposes + static class ConfigurationCreator { + + VmGcStatConfiguration create(ConfigurationInfoSource source) { + return new VmGcStatConfiguration(source); + } + + } }
--- a/plugins/vm-gc/common/src/test/java/com/redhat/thermostat/vm/gc/common/internal/ActivatorTest.java Wed May 31 12:06:16 2017 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,74 +0,0 @@ -/* - * Copyright 2012-2017 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.gc.common.internal; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import org.junit.Test; - -import com.redhat.thermostat.common.config.experimental.ConfigurationInfoSource; -import com.redhat.thermostat.testutils.StubBundleContext; -import com.redhat.thermostat.vm.gc.common.internal.Activator.VmGcStatDAOCreator; - -public class ActivatorTest { - - @Test - public void verifyActivatorRegistersServices() throws Exception { - VmGcStatDAOCreator creator = mock(VmGcStatDAOCreator.class); - VmGcStatDAOImpl dao = mock(VmGcStatDAOImpl.class); - when(creator.createDAO(any(VmGcStatConfiguration.class))).thenReturn(dao); - - ConfigurationInfoSource source = mock(ConfigurationInfoSource.class); - StubBundleContext context = new StubBundleContext(); - context.registerService(ConfigurationInfoSource.class.getName(), source, null); - - Activator activator = new Activator(creator); - - activator.start(context); - - assertEquals(2, context.getAllServices().size()); - - activator.stop(context); - - assertEquals(0, context.getServiceListeners().size()); - assertEquals(1, context.getAllServices().size()); - } - -} \ No newline at end of file
--- a/plugins/vm-gc/common/src/test/java/com/redhat/thermostat/vm/gc/common/internal/VmGcStatDAOTest.java Wed May 31 12:06:16 2017 -0400 +++ b/plugins/vm-gc/common/src/test/java/com/redhat/thermostat/vm/gc/common/internal/VmGcStatDAOTest.java Fri Jun 02 11:29:26 2017 -0400 @@ -57,8 +57,10 @@ import org.junit.Before; import org.junit.Test; +import com.redhat.thermostat.common.config.experimental.ConfigurationInfoSource; import com.redhat.thermostat.storage.core.Key; import com.redhat.thermostat.vm.gc.common.VmGcStatDAO; +import com.redhat.thermostat.vm.gc.common.internal.VmGcStatDAOImpl.ConfigurationCreator; import com.redhat.thermostat.vm.gc.common.internal.VmGcStatDAOImpl.HttpHelper; import com.redhat.thermostat.vm.gc.common.internal.VmGcStatDAOImpl.JsonHelper; import com.redhat.thermostat.vm.gc.common.model.VmGcStat; @@ -76,7 +78,7 @@ private StringContentProvider contentProvider; private Request request; private ContentResponse response; - private VmGcStatDAO dao; + private VmGcStatDAOImpl dao; @Before public void setup() throws Exception { @@ -101,13 +103,17 @@ contentProvider = mock(StringContentProvider.class); when(httpHelper.createContentProvider(anyString())).thenReturn(contentProvider); + ConfigurationInfoSource source = mock(ConfigurationInfoSource.class); VmGcStatConfiguration config = mock(VmGcStatConfiguration.class); when(config.getGatewayURL()).thenReturn(GATEWAY_URL); - dao = new VmGcStatDAOImpl(config, httpClient, jsonHelper, httpHelper); + ConfigurationCreator creator = mock(ConfigurationCreator.class); + when(creator.create(source)).thenReturn(config); + dao = new VmGcStatDAOImpl(httpClient, jsonHelper, httpHelper, creator, source); } @Test public void verifyAddVmGcStat() throws Exception { + dao.activate(); dao.putVmGcStat(stat); verify(httpClient).newRequest(GATEWAY_URL);
--- a/plugins/vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/internal/VmMemoryBackend.java Wed May 31 12:06:16 2017 -0400 +++ b/plugins/vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/internal/VmMemoryBackend.java Fri Jun 02 11:29:26 2017 -0400 @@ -55,10 +55,11 @@ VmStatusListenerRegistrar registrar, WriterID writerId) { super("VM Memory Backend", "Gathers memory statistics about a JVM", - "Red Hat, Inc.", version.getVersionNumber(), - true, registrar, writerId); + "Red Hat, Inc.", + true); this.vmMemoryStats = vmMemoryStatDAO; this.tlabStats = vmTlabStatDAO; + initialize(writerId, registrar, version.getVersionNumber()); } @Override
--- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/SystemBackend.java Wed May 31 12:06:16 2017 -0400 +++ b/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/SystemBackend.java Fri Jun 02 11:29:26 2017 -0400 @@ -85,12 +85,13 @@ super("System Backend", "Gathers basic information from the system", "Red Hat, Inc.", - version.getVersionNumber(), true); + true); this.networkInterfaces = netInfoDAO; this.vmInfoDAO = vmInfoDAO; this.notifier = notifier; this.writerId = writerId; this.blacklist = blacklist; + setVersion(version.getVersionNumber()); userInfoBuilder = InfoBuilderFactory.INSTANCE.createProcessUserInfoBuilder(userNameUtil); networkInfoBuilder = new NetworkInfoBuilder(writerId);