changeset 2680:8babf77875ec

Move GC plugin to Declarative Services Reviewed-by: jkang Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2017-May/023387.html
author Elliott Baron <ebaron@redhat.com>
date Fri, 02 Jun 2017 11:29:26 -0400
parents b88b3c8a79c7
children 1f8eb72c6f54
files agent/core/src/main/java/com/redhat/thermostat/backend/BaseBackend.java agent/core/src/main/java/com/redhat/thermostat/backend/PollingBackend.java agent/core/src/main/java/com/redhat/thermostat/backend/VmListenerBackend.java agent/core/src/test/java/com/redhat/thermostat/backend/BaseBackendTest.java agent/core/src/test/java/com/redhat/thermostat/backend/VmListenerBackendTest.java plugins/host-overview/agent/src/main/java/com/redhat/thermostat/host/overview/internal/HostOverviewBackend.java plugins/host-overview/agent/src/test/java/com/redhat/thermostat/host/overview/internal/HostOverviewBackendTest.java plugins/vm-gc/agent/pom.xml plugins/vm-gc/agent/src/main/java/com/redhat/thermostat/vm/gc/agent/internal/Activator.java plugins/vm-gc/agent/src/main/java/com/redhat/thermostat/vm/gc/agent/internal/VmGcBackend.java plugins/vm-gc/agent/src/test/java/com/redhat/thermostat/vm/gc/agent/internal/ActivatorTest.java plugins/vm-gc/agent/src/test/java/com/redhat/thermostat/vm/gc/agent/internal/VmGcBackendTest.java plugins/vm-gc/common/pom.xml plugins/vm-gc/common/src/main/java/com/redhat/thermostat/vm/gc/common/internal/Activator.java plugins/vm-gc/common/src/main/java/com/redhat/thermostat/vm/gc/common/internal/VmGcStatDAOImpl.java plugins/vm-gc/common/src/test/java/com/redhat/thermostat/vm/gc/common/internal/ActivatorTest.java plugins/vm-gc/common/src/test/java/com/redhat/thermostat/vm/gc/common/internal/VmGcStatDAOTest.java plugins/vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/internal/VmMemoryBackend.java system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/SystemBackend.java
diffstat 19 files changed, 342 insertions(+), 489 deletions(-) [+]
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);