changeset 673:9a952b5d6b3c

Use VmClassStatDAO as a service Make sure that VmClassStatDAO is either obtained directly from a class that creates it or through OSGi as a service, but never through DaoFactory. Reviewed-by: jerboaa Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2012-September/003492.html
author Omair Majid <omajid@redhat.com>
date Wed, 03 Oct 2012 18:05:54 -0400
parents 161aa00723d5
children ec7b20408616
files agent/core/src/main/java/com/redhat/thermostat/backend/system/JvmStatHostListener.java agent/core/src/main/java/com/redhat/thermostat/backend/system/JvmStatVmClassListener.java agent/core/src/main/java/com/redhat/thermostat/backend/system/SystemBackend.java agent/core/src/test/java/com/redhat/thermostat/backend/system/JvmStatHostListenerTest.java agent/core/src/test/java/com/redhat/thermostat/backend/system/JvmStatVmClassListenerTest.java client/vmclassstat/src/main/java/com/redhat/thermostat/client/vmclassstat/Activator.java client/vmclassstat/src/main/java/com/redhat/thermostat/client/vmclassstat/VmClassStatController.java client/vmclassstat/src/main/java/com/redhat/thermostat/client/vmclassstat/VmClassStatService.java client/vmclassstat/src/test/java/com/redhat/thermostat/client/vmclassstat/ActivatorTest.java client/vmclassstat/src/test/java/com/redhat/thermostat/client/vmclassstat/VmClassStatControllerTest.java common/core/src/main/java/com/redhat/thermostat/test/StubServiceReference.java
diffstat 11 files changed, 152 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/agent/core/src/main/java/com/redhat/thermostat/backend/system/JvmStatHostListener.java	Wed Oct 03 18:05:54 2012 -0400
+++ b/agent/core/src/main/java/com/redhat/thermostat/backend/system/JvmStatHostListener.java	Wed Oct 03 18:05:54 2012 -0400
@@ -60,6 +60,7 @@
 import com.redhat.thermostat.agent.JvmStatusListener;
 import com.redhat.thermostat.agent.JvmStatusNotifier;
 import com.redhat.thermostat.common.dao.DAOFactory;
+import com.redhat.thermostat.common.dao.VmClassStatDAO;
 import com.redhat.thermostat.common.dao.VmInfoDAO;
 import com.redhat.thermostat.common.dao.VmMemoryStatDAO;
 import com.redhat.thermostat.common.model.VmInfo;
@@ -74,16 +75,19 @@
     private final DAOFactory df;
     private final VmInfoDAO vmInfoDAO;
     private final VmMemoryStatDAO vmMemoryStatDAO;
+    private final VmClassStatDAO vmClassStatDAO;
 
     private Map<Integer, MonitoredVm> monitoredVms  = new HashMap<>();
     private Map<MonitoredVm, List<VmListener>> registeredListeners  = new ConcurrentHashMap<>();
     
     private Set<JvmStatusListener> statusListeners = new CopyOnWriteArraySet<JvmStatusListener>();
 
-    JvmStatHostListener(DAOFactory df, VmInfoDAO vmInfoDAO, VmMemoryStatDAO vmMemoryStatDAO, boolean attachNew) {
+    JvmStatHostListener(DAOFactory df, VmInfoDAO vmInfoDAO, VmMemoryStatDAO vmMemoryStatDAO,
+            VmClassStatDAO vmClassStatDAO, boolean attachNew) {
         this.df = df;
         this.vmInfoDAO = vmInfoDAO;
         this.vmMemoryStatDAO = vmMemoryStatDAO;
+        this.vmClassStatDAO = vmClassStatDAO;
         this.attachNew = attachNew;        
     }
 
@@ -169,7 +173,7 @@
                 vm.addVmListener(listener);
                 listeners.add(listener);
                 
-                listener = new JvmStatVmClassListener(df, vmId);
+                listener = new JvmStatVmClassListener(vmClassStatDAO, vmId);
                 vm.addVmListener(listener);
                 listeners.add(listener);
                 
--- a/agent/core/src/main/java/com/redhat/thermostat/backend/system/JvmStatVmClassListener.java	Wed Oct 03 18:05:54 2012 -0400
+++ b/agent/core/src/main/java/com/redhat/thermostat/backend/system/JvmStatVmClassListener.java	Wed Oct 03 18:05:54 2012 -0400
@@ -57,8 +57,8 @@
     private VmClassStatDAO dao;
     private int vmId;
 
-    JvmStatVmClassListener(DAOFactory df, int vmId) {
-        this.dao = df.getVmClassStatsDAO();
+    JvmStatVmClassListener(VmClassStatDAO dao, int vmId) {
+        this.dao = dao;
         this.vmId = vmId;
     }
 
--- a/agent/core/src/main/java/com/redhat/thermostat/backend/system/SystemBackend.java	Wed Oct 03 18:05:54 2012 -0400
+++ b/agent/core/src/main/java/com/redhat/thermostat/backend/system/SystemBackend.java	Wed Oct 03 18:05:54 2012 -0400
@@ -131,7 +131,7 @@
         memoryStats = df.getMemoryStatDAO();
         vmCpuStats = df.getVmCpuStatDAO();
         networkInterfaces = df.getNetworkInterfaceInfoDAO();
-        hostListener = new JvmStatHostListener(df, df.getVmInfoDAO(), df.getVmMemoryStatDAO(), getObserveNewJvm());
+        hostListener = new JvmStatHostListener(df, df.getVmInfoDAO(), df.getVmMemoryStatDAO(), df.getVmClassStatsDAO(), getObserveNewJvm());
     }
 
     @Override
--- a/agent/core/src/test/java/com/redhat/thermostat/backend/system/JvmStatHostListenerTest.java	Wed Oct 03 18:05:54 2012 -0400
+++ b/agent/core/src/test/java/com/redhat/thermostat/backend/system/JvmStatHostListenerTest.java	Wed Oct 03 18:05:54 2012 -0400
@@ -82,8 +82,8 @@
         VmClassStatDAO vmClassDAO = mock(VmClassStatDAO.class);
         VmInfoDAO vmInfoDAO = mock(VmInfoDAO.class);
         DAOFactory df = mock(DAOFactory.class);
-        when(df.getVmClassStatsDAO()).thenReturn(vmClassDAO);
-        JvmStatHostListener l = new JvmStatHostListener(df, vmInfoDAO, null, true);
+
+        JvmStatHostListener l = new JvmStatHostListener(df, vmInfoDAO, null, vmClassDAO ,true);
         SystemBackend backend = mock(SystemBackend.class);
         when(backend.getObserveNewJvm()).thenReturn(true);
 
--- a/agent/core/src/test/java/com/redhat/thermostat/backend/system/JvmStatVmClassListenerTest.java	Wed Oct 03 18:05:54 2012 -0400
+++ b/agent/core/src/test/java/com/redhat/thermostat/backend/system/JvmStatVmClassListenerTest.java	Wed Oct 03 18:05:54 2012 -0400
@@ -61,9 +61,8 @@
     public void testMonitorUpdatedClassStat() throws Exception {
 
         VmClassStatDAO dao = mock(VmClassStatDAO.class);
-        DAOFactory df = mock(DAOFactory.class);
-        when(df.getVmClassStatsDAO()).thenReturn(dao);
-        JvmStatVmClassListener l = new JvmStatVmClassListener(df, VM_ID);
+
+        JvmStatVmClassListener l = new JvmStatVmClassListener(dao, VM_ID);
         VmEvent vmEvent = mock(VmEvent.class);
         MonitoredVm monitoredVm = mock(MonitoredVm.class);
         Monitor m = mock(Monitor.class);
@@ -84,9 +83,8 @@
     public void testMonitorUpdatedClassStatTwice() throws Exception {
 
         VmClassStatDAO dao = mock(VmClassStatDAO.class);
-        DAOFactory df = mock(DAOFactory.class);
-        when(df.getVmClassStatsDAO()).thenReturn(dao);
-        JvmStatVmClassListener l = new JvmStatVmClassListener(df, VM_ID);
+
+        JvmStatVmClassListener l = new JvmStatVmClassListener(dao, VM_ID);
         VmEvent vmEvent = mock(VmEvent.class);
         MonitoredVm monitoredVm = mock(MonitoredVm.class);
         Monitor m = mock(Monitor.class);
--- a/client/vmclassstat/src/main/java/com/redhat/thermostat/client/vmclassstat/Activator.java	Wed Oct 03 18:05:54 2012 -0400
+++ b/client/vmclassstat/src/main/java/com/redhat/thermostat/client/vmclassstat/Activator.java	Wed Oct 03 18:05:54 2012 -0400
@@ -36,29 +36,53 @@
 
 package com.redhat.thermostat.client.vmclassstat;
 
+import java.util.Map;
+import java.util.Objects;
+
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.framework.ServiceRegistration;
 
 import com.redhat.thermostat.client.osgi.service.ApplicationService;
 import com.redhat.thermostat.client.osgi.service.VmInformationService;
+import com.redhat.thermostat.common.MultipleServiceTracker;
+import com.redhat.thermostat.common.MultipleServiceTracker.Action;
+import com.redhat.thermostat.common.dao.VmClassStatDAO;
 
 public class Activator implements BundleActivator {
 
+    private MultipleServiceTracker classStatTracker;
+    private ServiceRegistration classStatRegistration;
+
     @Override
-    public void start(BundleContext context) throws Exception {
-        ServiceTracker tracker = new ServiceTracker(context, ApplicationService.class.getName(), null) {
+    public void start(final BundleContext context) throws Exception {
+
+        Class<?>[] deps = new Class<?>[] {
+            ApplicationService.class,
+            VmClassStatDAO.class,
+        };
+
+        classStatTracker = new MultipleServiceTracker(context, deps, new Action() {
+
             @Override
-            public Object addingService(ServiceReference reference) {
-                context.registerService(VmInformationService.class.getName(), new VmClassStatService(), null);
-                return super.addingService(reference);
+            public void dependenciesAvailable(Map<String, Object> services) {
+                VmClassStatDAO dao = (VmClassStatDAO) services.get(VmClassStatDAO.class.getName());
+                Objects.requireNonNull(dao);
+                VmClassStatService service = new VmClassStatService(dao);
+                classStatRegistration = context.registerService(VmInformationService.class.getName(), service, null);
             }
-        };
-        tracker.open();
+
+            @Override
+            public void dependenciesUnavailable() {
+                classStatRegistration.unregister();
+            }
+
+        });
+        classStatTracker.open();
     }
 
     @Override
     public void stop(BundleContext context) throws Exception {
+        classStatTracker.close();
     }
 }
--- a/client/vmclassstat/src/main/java/com/redhat/thermostat/client/vmclassstat/VmClassStatController.java	Wed Oct 03 18:05:54 2012 -0400
+++ b/client/vmclassstat/src/main/java/com/redhat/thermostat/client/vmclassstat/VmClassStatController.java	Wed Oct 03 18:05:54 2012 -0400
@@ -80,9 +80,9 @@
 
     private volatile long lastSeenTimeStamp = Long.MIN_VALUE;
 
-    public VmClassStatController(VmRef ref, VmClassStatViewProvider viewProvider) {
+    public VmClassStatController(VmClassStatDAO vmClassStatDao, VmRef ref, VmClassStatViewProvider viewProvider) {
         this.ref = ref;
-        dao = ApplicationContext.getInstance().getDAOFactory().getVmClassStatsDAO();
+        dao = vmClassStatDao;
         timer = ApplicationContext.getInstance().getTimerFactory().createTimer();
 
         timer.setAction(new UpdateChartData());
--- a/client/vmclassstat/src/main/java/com/redhat/thermostat/client/vmclassstat/VmClassStatService.java	Wed Oct 03 18:05:54 2012 -0400
+++ b/client/vmclassstat/src/main/java/com/redhat/thermostat/client/vmclassstat/VmClassStatService.java	Wed Oct 03 18:05:54 2012 -0400
@@ -40,6 +40,7 @@
 import com.redhat.thermostat.client.osgi.service.VmFilter;
 import com.redhat.thermostat.client.osgi.service.VmInformationService;
 import com.redhat.thermostat.client.osgi.service.VmInformationServiceController;
+import com.redhat.thermostat.common.dao.VmClassStatDAO;
 import com.redhat.thermostat.common.dao.VmRef;
 
 class VmClassStatService implements VmInformationService {
@@ -47,13 +48,17 @@
     private VmFilter filter = new AlwaysMatchFilter();
 
     private VmClassStatViewProvider viewProvider;
-    public VmClassStatService() {
+
+    private VmClassStatDAO vmClassStatDao;
+
+    public VmClassStatService(VmClassStatDAO vmClassStatDao) {
+        this.vmClassStatDao = vmClassStatDao;
         viewProvider = new VmClassStatViewProvider();
     }
     
     @Override
     public VmInformationServiceController getInformationServiceController(VmRef ref) {
-        return new VmClassStatController(ref, viewProvider);
+        return new VmClassStatController(vmClassStatDao, ref, viewProvider);
     }
 
     @Override
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/vmclassstat/src/test/java/com/redhat/thermostat/client/vmclassstat/ActivatorTest.java	Wed Oct 03 18:05:54 2012 -0400
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.vmclassstat;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+
+import org.junit.Test;
+
+import com.redhat.thermostat.client.osgi.service.ApplicationService;
+import com.redhat.thermostat.client.osgi.service.VmInformationService;
+import com.redhat.thermostat.common.dao.VmClassStatDAO;
+import com.redhat.thermostat.test.StubBundleContext;
+
+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());
+        assertNotSame(0, context.getServiceListeners().size());
+
+        activator.stop(context);
+
+        assertEquals(0, context.getServiceListeners().size());
+    }
+
+    @Test
+    public void verifyActivatorRegistersServices() throws Exception {
+        StubBundleContext context = new StubBundleContext();
+        ApplicationService appService = mock(ApplicationService.class);
+        VmClassStatDAO daoService = mock(VmClassStatDAO.class);
+
+        context.registerService(ApplicationService.class, appService, null);
+        context.registerService(VmClassStatDAO.class, daoService, null);
+
+        Activator activator = new Activator();
+
+        activator.start(context);
+
+        assertTrue(context.isServiceRegistered(VmInformationService.class.getName(), VmClassStatService.class));
+
+        activator.stop(context);
+
+        assertEquals(0, context.getServiceListeners().size());
+        assertEquals(2, context.getAllServices().size());
+    }
+}
--- a/client/vmclassstat/src/test/java/com/redhat/thermostat/client/vmclassstat/VmClassStatControllerTest.java	Wed Oct 03 18:05:54 2012 -0400
+++ b/client/vmclassstat/src/test/java/com/redhat/thermostat/client/vmclassstat/VmClassStatControllerTest.java	Wed Oct 03 18:05:54 2012 -0400
@@ -54,8 +54,6 @@
 import com.redhat.thermostat.common.Timer;
 import com.redhat.thermostat.common.TimerFactory;
 import com.redhat.thermostat.common.appctx.ApplicationContext;
-import com.redhat.thermostat.common.dao.DAOFactory;
-import com.redhat.thermostat.common.dao.MongoDAOFactory;
 import com.redhat.thermostat.common.dao.VmClassStatDAO;
 import com.redhat.thermostat.common.dao.VmRef;
 import com.redhat.thermostat.common.model.VmClassStat;
@@ -73,10 +71,6 @@
         VmClassStatDAO vmClassStatDAO = mock(VmClassStatDAO.class);
         when(vmClassStatDAO.getLatestClassStats(any(VmRef.class), anyInt())).thenReturn(stats).thenReturn(new ArrayList<VmClassStat>());
 
-        DAOFactory daoFactory = mock(MongoDAOFactory.class);
-        when(daoFactory.getVmClassStatsDAO()).thenReturn(vmClassStatDAO);
-
-        ApplicationContext.getInstance().setDAOFactory(daoFactory);
         VmRef ref = mock(VmRef.class);
 
         Timer timer = mock(Timer.class);
@@ -94,7 +88,7 @@
         VmClassStatViewProvider viewFactory = mock(VmClassStatViewProvider.class);
         when(viewFactory.createView()).thenReturn(view);
 
-        VmClassStatController controller = new VmClassStatController(ref, viewFactory);
+        VmClassStatController controller = new VmClassStatController(vmClassStatDAO, ref, viewFactory);
 
         ActionListener<VmClassStatView.Action> l = viewArgumentCaptor.getValue();
 
--- a/common/core/src/main/java/com/redhat/thermostat/test/StubServiceReference.java	Wed Oct 03 18:05:54 2012 -0400
+++ b/common/core/src/main/java/com/redhat/thermostat/test/StubServiceReference.java	Wed Oct 03 18:05:54 2012 -0400
@@ -37,6 +37,7 @@
 package com.redhat.thermostat.test;
 
 import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceReference;
 
 import com.redhat.thermostat.common.NotImplementedException;
@@ -52,6 +53,10 @@
 
     @Override
     public Object getProperty(String key) {
+        if (Constants.OBJECTCLASS.equals(key)) {
+            return new String[] { information.serviceInterface };
+        }
+
         throw new NotImplementedException();
     }