changeset 1996:df9c589c6e0c

Fix registration of thread backends. PR3069, PR3054 Reviewed-by: neugens Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2016-June/020064.html
author Jie Kang <jkang@redhat.com>
date Thu, 30 Jun 2016 08:43:12 -0400
parents 116f7c9007cc
children cbf98b5f488d
files thread/harvester/src/main/java/com/redhat/thermostat/thread/harvester/osgi/Activator.java thread/harvester/src/test/java/com/redhat/thermostat/thread/harvester/osgi/ActivatorTest.java
diffstat 2 files changed, 86 insertions(+), 87 deletions(-) [+]
line wrap: on
line diff
--- a/thread/harvester/src/main/java/com/redhat/thermostat/thread/harvester/osgi/Activator.java	Wed Jun 29 10:37:20 2016 -0400
+++ b/thread/harvester/src/main/java/com/redhat/thermostat/thread/harvester/osgi/Activator.java	Thu Jun 30 08:43:12 2016 -0400
@@ -51,6 +51,7 @@
 import com.redhat.thermostat.agent.command.ReceiverRegistry;
 import com.redhat.thermostat.agent.utils.management.MXBeanConnectionPool;
 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.Version;
@@ -62,16 +63,7 @@
 
 public class Activator implements BundleActivator {
     
-    private ScheduledExecutorService executor = Executors.newScheduledThreadPool(24);
-
-    private MultipleServiceTracker connectionPoolTracker;
-    private ServiceTracker threadDaoTracker;
-    private ServiceRegistration backendRegistration;
-
-    private ReceiverRegistry registry;
-    private ThreadHarvester harvester;
-    private ThreadBackend backend;
-
+    private MultipleServiceTracker threadBackendTracker;
     private MultipleServiceTracker threadCountTracker;
     
     @Override
@@ -81,96 +73,82 @@
             = new VmStatusListenerRegistrar(context);
 
         Class<?>[] threadCountDeps = new Class<?>[] {
+                BackendService.class,
                 WriterID.class,
                 ThreadDao.class,
         };
         threadCountTracker = new MultipleServiceTracker(context, threadCountDeps, new Action() {
 
             private ServiceRegistration<Backend> registration;
+            private ThreadCountBackend threadCountBackend;
 
             @Override
             public void dependenciesAvailable(Map<String, Object> services) {
                 WriterID writerId = (WriterID) services.get(WriterID.class.getName());
                 ThreadDao dao = (ThreadDao) services.get(ThreadDao.class.getName());
                 Objects.requireNonNull(dao);
-                ThreadCountBackend threadCountBackend = new ThreadCountBackend(dao, VERSION, VM_STATUS_REGISTRAR, writerId);
+                threadCountBackend = new ThreadCountBackend(dao, VERSION, VM_STATUS_REGISTRAR, writerId);
                 registration = context.registerService(Backend.class, threadCountBackend, null);
             }
 
             @Override
             public void dependenciesUnavailable() {
+                if (threadCountBackend.isActive()) {
+                    threadCountBackend.deactivate();
+                }
                 registration.unregister();
-                registration = null;
             }
         });
         threadCountTracker.open();
-        
+
         Class<?>[] deps = new Class<?>[] {
+                BackendService.class,
                 MXBeanConnectionPool.class,
                 WriterID.class,
+                ThreadDao.class,
         };
-        connectionPoolTracker = new MultipleServiceTracker(context, deps, new Action() {
-            
+        threadBackendTracker = new MultipleServiceTracker(context, deps, new Action() {
+
+            private ServiceRegistration<Backend> registration;
+            private ThreadBackend threadBackend;
+            private ScheduledExecutorService executor;
+
             @Override
             public void dependenciesAvailable(Map<String, Object> services) {
                 MXBeanConnectionPool pool = (MXBeanConnectionPool) services.get(MXBeanConnectionPool.class.getName());
                 WriterID writerId = (WriterID) services.get(WriterID.class.getName());
-                harvester = new ThreadHarvester(executor, pool, writerId);
+                ThreadDao threadDao = (ThreadDao) services.get(ThreadDao.class.getName());
+
+                executor = Executors.newScheduledThreadPool(24);
+                ThreadHarvester harvester = new ThreadHarvester(executor, pool, writerId);
+                harvester.setThreadDao(threadDao);
+
+                ReceiverRegistry registry = new ReceiverRegistry(context);
+                threadBackend = new ThreadBackend(VERSION, VM_STATUS_REGISTRAR, registry, harvester);
+                registration = context.registerService(Backend.class, threadBackend, null);
             }
 
             @Override
             public void dependenciesUnavailable() {
-                harvester = null;
+                if (executor != null) {
+                    executor.shutdown();
+                }
+
+                if (threadBackend.isActive()) {
+                    threadBackend.deactivate();
+                }
+                if (registration != null) {
+                    registration.unregister();
+                }
             }
         });
-        connectionPoolTracker.open();
-
-        registry = new ReceiverRegistry(context);
-
-        /*
-         * dont register anything just yet, let the backend handle the
-         * registration, deregistration it when it's activated or deactivated
-         */
-
-        backend = new ThreadBackend(VERSION, VM_STATUS_REGISTRAR, registry, harvester);
-        backendRegistration = context.registerService(Backend.class, backend, null);
-
-        threadDaoTracker = new ServiceTracker(context, ThreadDao.class.getName(), null) {
-            @Override
-            public Object addingService(ServiceReference reference) {
-                ThreadDao threadDao = (ThreadDao) context.getService(reference);
-                harvester.setThreadDao(threadDao);
-                return super.addingService(reference);
-            }
-
-            @Override
-            public void removedService(ServiceReference reference, Object service) {
-                if (harvester != null) {
-                    harvester.setThreadDao(null);
-                }
-                context.ungetService(reference);
-                super.removedService(reference, service);
-            }
-        };
-        threadDaoTracker.open();
+        threadBackendTracker.open();
     }
 
     @Override
     public void stop(BundleContext context) throws Exception {
-        if (backend.isActive()) {
-            backend.deactivate();
-        }
-
         threadCountTracker.close();
-
-        backendRegistration.unregister();
-
-        connectionPoolTracker.close();
-        threadDaoTracker.close();
-
-        if (executor != null) {
-            executor.shutdown();
-        }        
+        threadBackendTracker.close();
     }
 }
 
--- a/thread/harvester/src/test/java/com/redhat/thermostat/thread/harvester/osgi/ActivatorTest.java	Wed Jun 29 10:37:20 2016 -0400
+++ b/thread/harvester/src/test/java/com/redhat/thermostat/thread/harvester/osgi/ActivatorTest.java	Thu Jun 30 08:43:12 2016 -0400
@@ -36,6 +36,7 @@
 
 package com.redhat.thermostat.thread.harvester.osgi;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
@@ -46,46 +47,66 @@
 import org.osgi.framework.Bundle;
 import org.osgi.framework.Version;
 
+import com.redhat.thermostat.agent.utils.management.MXBeanConnectionPool;
+import com.redhat.thermostat.backend.Backend;
+import com.redhat.thermostat.backend.BackendService;
 import com.redhat.thermostat.backend.VmUpdateListener;
 import com.redhat.thermostat.storage.core.WriterID;
 import com.redhat.thermostat.testutils.StubBundleContext;
 import com.redhat.thermostat.thread.dao.ThreadDao;
+import com.redhat.thermostat.thread.harvester.ThreadBackend;
 import com.redhat.thermostat.thread.harvester.ThreadCountBackend;
 
 public class ActivatorTest {
 
-    private Bundle bundle;
-    private Version version;
-    private WriterID writerId;
-    private ThreadDao threadDao;
-
-    @Before
-    public void setUp() {
-        version = new Version("0.1.2");
-
-        bundle = mock(Bundle.class);
-        when(bundle.getVersion()).thenReturn(version);
-
-        writerId = mock(WriterID.class);
-
-        threadDao = mock(ThreadDao.class);
-    }
-
-    @Ignore("Activator assumes that Harvester is always registered and fails with NullPointerException")
     @Test
-    public void verifyThreadCountUpdaterIsRegistered() throws Exception {
-        StubBundleContext bundleContext = new StubBundleContext();
-        bundleContext.setBundle(bundle);
-
-        bundleContext.registerService(WriterID.class, writerId, null);
-        bundleContext.registerService(ThreadDao.class, threadDao, null);
+    public void verifyActivatorDoesNotRegisterServiceOnMissingDeps() throws Exception {
+        StubBundleContext context = new StubBundleContext();
 
         Activator activator = new Activator();
 
-        activator.start(bundleContext);
+        activator.start(context);
+
+        assertEquals(0, context.getAllServices().size());
+        assertEquals(7, 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;
+            }
+        };
 
-        assertTrue(bundleContext.isServiceRegistered(VmUpdateListener.class.getName(), ThreadCountBackend.class));
+        BackendService backendService = mock(BackendService.class);
+        WriterID idService = mock(WriterID.class);
+        ThreadDao threadDao = mock(ThreadDao.class);
+        MXBeanConnectionPool mxBeanConnectionPool = mock(MXBeanConnectionPool.class);
+
+        context.registerService(BackendService.class.getName(), backendService, null);
+        context.registerService(WriterID.class, idService, null);
+        context.registerService(ThreadDao.class, threadDao, null);
+        context.registerService(MXBeanConnectionPool.class, mxBeanConnectionPool, null);
+
+        Activator activator = new Activator();
 
-        activator.stop(bundleContext);
+        activator.start(context);
+
+        assertTrue(context.isServiceRegistered(Backend.class.getName(), ThreadCountBackend.class));
+        assertTrue(context.isServiceRegistered(Backend.class.getName(), ThreadBackend.class));
+
+        assertEquals(6, context.getAllServices().size());
+        assertEquals(7, context.getServiceListeners().size());
+
+        activator.stop(context);
+
+        assertEquals(4, context.getAllServices().size());
+        assertEquals(0, context.getServiceListeners().size());
     }
 }