# HG changeset patch # User Jie Kang # Date 1467290592 14400 # Node ID df9c589c6e0c8a194a30c0eca6632b282c11416e # Parent 116f7c9007cce34e012c09c837093bb893984c20 Fix registration of thread backends. PR3069, PR3054 Reviewed-by: neugens Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2016-June/020064.html diff -r 116f7c9007cc -r df9c589c6e0c thread/harvester/src/main/java/com/redhat/thermostat/thread/harvester/osgi/Activator.java --- 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 registration; + private ThreadCountBackend threadCountBackend; @Override public void dependenciesAvailable(Map 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 registration; + private ThreadBackend threadBackend; + private ScheduledExecutorService executor; + @Override public void dependenciesAvailable(Map 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(); } } diff -r 116f7c9007cc -r df9c589c6e0c thread/harvester/src/test/java/com/redhat/thermostat/thread/harvester/osgi/ActivatorTest.java --- 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()); } }