Package: CoreBundleActivator

CoreBundleActivator

nameinstructionbranchcomplexitylinemethod
CoreBundleActivator()
M: 6 C: 13
68%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
activate(ComponentContext)
M: 0 C: 74
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 13
100%
M: 0 C: 1
100%
createAndRegisterApplicationContextDependencyMonitor(BundleContext, EventLogger)
M: 6 C: 33
85%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 6
100%
M: 0 C: 1
100%
createAndRegisterBundleStartTracker(BundleContext)
M: 6 C: 63
91%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 8
100%
M: 0 C: 1
100%
createAndRegisterBundleStarter(BundleStartTracker, BundleContext)
M: 6 C: 30
83%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
createAndRegisterStateDumpContributors(BundleContext)
M: 6 C: 23
79%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
createShutdown(BundleContext, EventLogger)
M: 22 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 4 C: 0
0%
M: 1 C: 0
0%
deactivate(ComponentContext)
M: 6 C: 32
84%
M: 2 C: 2
50%
M: 2 C: 1
33%
M: 0 C: 13
100%
M: 0 C: 1
100%
getRequiredService(BundleContext, Class)
M: 0 C: 42
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 8
100%
M: 0 C: 1
100%
initShimServices(BundleContext, EventLogger)
M: 6 C: 28
82%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
initializeShutdownManager(BundleContext, EventLogger, KernelConfiguration)
M: 6 C: 20
77%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
registerShutdownMBean(KernelConfiguration, Shutdown)
M: 13 C: 19
59%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 1 C: 5
83%
M: 0 C: 1
100%
unregisterShutdownMBean()
M: 6 C: 13
68%
M: 1 C: 1
50%
M: 1 C: 1
50%
M: 0 C: 5
100%
M: 0 C: 1
100%

Coverage

1: /*******************************************************************************
2: * Copyright (c) 2008, 2010 VMware Inc.
3: * All rights reserved. This program and the accompanying materials
4: * are made available under the terms of the Eclipse Public License v1.0
5: * which accompanies this distribution, and is available at
6: * http://www.eclipse.org/legal/epl-v10.html
7: *
8: * Contributors:
9: * VMware Inc. - initial contribution
10: *******************************************************************************/
11:
12: package org.eclipse.virgo.nano.core.internal;
13:
14: import java.lang.management.ManagementFactory;
15: import java.util.Dictionary;
16: import java.util.Hashtable;
17: import java.util.concurrent.BlockingQueue;
18: import java.util.concurrent.Executors;
19: import java.util.concurrent.ScheduledExecutorService;
20: import java.util.concurrent.SynchronousQueue;
21: import java.util.concurrent.ThreadFactory;
22: import java.util.concurrent.ThreadPoolExecutor;
23: import java.util.concurrent.TimeUnit;
24: import java.util.concurrent.atomic.AtomicLong;
25:
26: import javax.management.InstanceNotFoundException;
27: import javax.management.JMException;
28: import javax.management.MBeanRegistrationException;
29: import javax.management.MBeanServer;
30: import javax.management.ObjectInstance;
31: import javax.management.ObjectName;
32:
33: import org.eclipse.virgo.nano.config.internal.KernelConfiguration;
34: import org.eclipse.virgo.nano.config.internal.ConfigurationInitialiser;
35: import org.eclipse.virgo.nano.core.BundleStarter;
36: import org.eclipse.virgo.nano.core.Shutdown;
37: import org.eclipse.virgo.nano.core.internal.blueprint.ApplicationContextDependencyMonitor;
38: import org.eclipse.virgo.nano.serviceability.dump.internal.RegionDigraphDumpContributor;
39: import org.eclipse.virgo.nano.serviceability.dump.internal.ResolutionDumpContributor;
40: import org.eclipse.virgo.nano.shim.scope.ScopeFactory;
41: import org.eclipse.virgo.nano.shim.scope.internal.StandardScopeFactory;
42: import org.eclipse.virgo.nano.shim.serviceability.TracingService;
43: import org.eclipse.virgo.nano.shim.serviceability.internal.Slf4jTracingService;
44: import org.eclipse.virgo.medic.dump.DumpContributor;
45: import org.eclipse.virgo.medic.dump.DumpGenerator;
46: import org.eclipse.virgo.medic.eventlog.EventLogger;
47: import org.eclipse.virgo.util.osgi.ServiceRegistrationTracker;
48: import org.osgi.framework.BundleContext;
49: import org.osgi.framework.ServiceReference;
50: import org.osgi.framework.launch.Framework;
51: import org.osgi.service.component.ComponentContext;
52: import org.osgi.service.event.EventConstants;
53: import org.osgi.service.event.EventHandler;
54:
55: /**
56: * ComponentContext activator that initialises the core of the Kernel.
57: *
58: * <strong>Concurrent Semantics</strong><br />
59: * Threadsafe.
60: *
61: */
62: public class CoreBundleActivator {
63:
64: private static final String START_SIGNALLING_THREAD_NAME_PREFIX = "start-signalling-";
65:
66: private static final String PROPERTY_NAME_SERVICE_SCOPE = "org.eclipse.virgo.service.scope";
67:
68: private static final String SERVICE_SCOPE_GLOBAL = "global";
69:
70: private static final String EVENT_TOPIC_BLUEPRINT_CONTAINER = "org/osgi/service/blueprint/container/*";
71:
72: private static final String EVENT_TOPIC_REGION = "org/eclipse/virgo/kernel/region/*";
73:
74: private static final String MBEAN_VALUE_SHUTDOWN = "Shutdown";
75:
76: private static final String MBEAN_KEY_TYPE = "type";
77:
78: private final ServiceRegistrationTracker tracker = new ServiceRegistrationTracker();
79:
80: private final ConfigurationInitialiser configurationInitialiser = new ConfigurationInitialiser();
81:
82: private volatile StartupTracker startupTracker;
83:
84: private volatile ObjectInstance shutdownMBean;
85:
86: private volatile ApplicationContextDependencyMonitor dependencyMonitor;
87:
88: private volatile BundleStartTracker bundleStartTracker;
89:
90: public void activate(ComponentContext componentContext) throws Exception {
91: BundleContext context = componentContext.getBundleContext();
92:
93: EventLogger eventLogger = getRequiredService(context, EventLogger.class);
94:
95: KernelConfiguration configuration = this.configurationInitialiser.start(context, eventLogger);
96: Shutdown shutdown = initializeShutdownManager(context, eventLogger, configuration);
97:
98: this.bundleStartTracker = createAndRegisterBundleStartTracker(context);         
99: createAndRegisterBundleStarter(this.bundleStartTracker, context);
100:
101: this.dependencyMonitor = createAndRegisterApplicationContextDependencyMonitor(context, eventLogger);
102:
103: DumpGenerator dumpGenerator = getRequiredService(context, DumpGenerator.class);
104:
105: createAndRegisterStateDumpContributors(context);
106:
107: this.startupTracker = new StartupTracker(context, configuration, configuration.getStartupWaitLimit(), bundleStartTracker, shutdown, dumpGenerator);
108: this.startupTracker.start();
109:
110: initShimServices(context, eventLogger);
111: }
112:
113: private void createAndRegisterStateDumpContributors(BundleContext context) {
114: this.tracker.track(context.registerService(DumpContributor.class, new ResolutionDumpContributor(context), null));
115: this.tracker.track(context.registerService(DumpContributor.class, new RegionDigraphDumpContributor(context), null));
116: }
117:
118: private ApplicationContextDependencyMonitor createAndRegisterApplicationContextDependencyMonitor(BundleContext context, EventLogger eventLogger) {
119: ScheduledExecutorService scheduledExecutor = Executors.newScheduledThreadPool(1, new ThreadFactory() {
120: private AtomicLong threadCount = new AtomicLong(1);
121:
122: public Thread newThread(Runnable r) {
123: String name = "service-monitor-thread-" + this.threadCount.getAndIncrement();
124: return new Thread(r, name);
125: }
126: });
127:
128: ApplicationContextDependencyMonitor dependencyMonitor = new ApplicationContextDependencyMonitor(scheduledExecutor, eventLogger);
129:
130: Dictionary<String, String> properties = new Hashtable<String, String>();
131: properties.put(EventConstants.EVENT_TOPIC, EVENT_TOPIC_BLUEPRINT_CONTAINER);
132:
133: this.tracker.track(context.registerService(EventHandler.class.getName(), dependencyMonitor, properties));
134:
135: return dependencyMonitor;
136: }
137:
138: @SuppressWarnings("unchecked")
139: private BundleStartTracker createAndRegisterBundleStartTracker(BundleContext context) {
140:         BlockingQueue q = new SynchronousQueue();
141:         ThreadPoolExecutor executor = new ThreadPoolExecutor(1, Integer.MAX_VALUE, 60, TimeUnit.SECONDS, q, new PrefixingThreadFactory(START_SIGNALLING_THREAD_NAME_PREFIX), new ThreadPoolExecutor.AbortPolicy());
142:         BundleStartTracker asynchronousStartTracker = new BundleStartTracker(executor);
143:         asynchronousStartTracker.initialize(context);
144:         
145:         Dictionary<String, Object> properties = new Hashtable<String, Object>();
146: properties.put(EventConstants.EVENT_TOPIC, new String[] {EVENT_TOPIC_BLUEPRINT_CONTAINER, EVENT_TOPIC_REGION});
147:
148: this.tracker.track(context.registerService(new String[] {EventHandler.class.getName()}, asynchronousStartTracker, properties));
149:
150: return asynchronousStartTracker;
151: }
152:
153: private BundleStarter createAndRegisterBundleStarter(BundleStartTracker asynchronousStartTracker, BundleContext bundleContext) {
154:         
155: StandardBundleStarter bundleStarter = new StandardBundleStarter(asynchronousStartTracker);
156: Dictionary<String, Object> properties = new Hashtable<String, Object>();
157: properties.put(PROPERTY_NAME_SERVICE_SCOPE, SERVICE_SCOPE_GLOBAL);
158:
159: this.tracker.track(bundleContext.registerService(new String[] {BundleStarter.class.getName()}, bundleStarter, properties));
160:
161: return bundleStarter;
162: }
163:
164: public void deactivate(ComponentContext context) throws Exception {
165: this.tracker.unregisterAll();
166: this.startupTracker.stop();
167: this.configurationInitialiser.stop();
168:
169: unregisterShutdownMBean();
170:
171: ApplicationContextDependencyMonitor dependencyMonitor = this.dependencyMonitor;
172:• if (dependencyMonitor != null) {
173: this.dependencyMonitor = null;
174: dependencyMonitor.stop();
175: }
176:
177: BundleStartTracker bundleStartTracker = this.bundleStartTracker;
178:• if (bundleStartTracker != null) {
179: this.bundleStartTracker = null;
180: bundleStartTracker.stop();
181: }
182: }
183:
184: private Shutdown initializeShutdownManager(BundleContext context, EventLogger eventLogger, KernelConfiguration configuration) {
185: Shutdown shutdown = createShutdown(context, eventLogger);
186: this.tracker.track(context.registerService(org.eclipse.virgo.nano.core.Shutdown.class.getName(), shutdown, null));
187:
188: registerShutdownMBean(configuration, shutdown);
189: return shutdown;
190: }
191:
192: private void registerShutdownMBean(KernelConfiguration configuration, Shutdown shutdown) {
193: MBeanServer server = ManagementFactory.getPlatformMBeanServer();
194:
195: try {
196: ObjectName shutdownName = ObjectName.getInstance(configuration.getDomain(), MBEAN_KEY_TYPE, MBEAN_VALUE_SHUTDOWN);
197: this.shutdownMBean = server.registerMBean(new AsyncShutdownDecorator(shutdown), shutdownName);
198: } catch (JMException ex) {
199: throw new IllegalStateException("Unable to register Shutdown MBean", ex);
200: }
201: }
202:
203: private void unregisterShutdownMBean() throws MBeanRegistrationException, InstanceNotFoundException {
204: ObjectInstance localShutdownMBean = this.shutdownMBean;
205:• if (localShutdownMBean != null) {
206: ManagementFactory.getPlatformMBeanServer().unregisterMBean(localShutdownMBean.getObjectName());
207: this.shutdownMBean = null;
208: }
209: }
210:
211: protected Shutdown createShutdown(BundleContext context, EventLogger eventLogger) {
212: Framework framework = (Framework) context.getBundle(0);
213: Runtime runtime = Runtime.getRuntime();
214: ShutdownManager manager = new ShutdownManager(eventLogger, framework, runtime);
215: return manager;
216: }
217:
218: private void initShimServices(BundleContext context, EventLogger eventLogger) {
219: ScopeFactory scopeFactory = new StandardScopeFactory(eventLogger);
220: TracingService tracingService = new Slf4jTracingService();
221: this.tracker.track(context.registerService(ScopeFactory.class.getName(), scopeFactory, null));
222: this.tracker.track(context.registerService(TracingService.class.getName(), tracingService, null));
223: }
224:
225: private <T> T getRequiredService(BundleContext context, Class<T> clazz) {
226: T result = null;
227: ServiceReference<T> ref = context.getServiceReference(clazz);
228:• if (ref != null) {
229: result = context.getService(ref);
230: }
231:• if (result == null) {
232: throw new IllegalStateException("Unable to access required service of type '" + clazz.getName() + "' from bundle '"
233: + context.getBundle().getSymbolicName() + "'");
234: }
235: return result;
236: }
237:
238: private class PrefixingThreadFactory implements ThreadFactory {
239:                 private int threadCount = 0;
240:                 private final Object threadCountMonitor = new Object();
241:                 String prefix = "default-thread-prefix";
242:                 
243:                 public PrefixingThreadFactory(String prefix) {
244:                         this.prefix = prefix;
245:                 }
246:                 
247:                 @Override
248:                 public Thread newThread(Runnable r) {
249:                         return new Thread(r, nextThreadName());
250:                 }
251:                 
252:                 private String nextThreadName() {
253:                         int threadNumber = 0;
254:                         synchronized (this.threadCountMonitor) {
255:                                 this.threadCount++;
256:                                 threadNumber = this.threadCount;
257:                         }
258:                         return this.prefix + threadNumber;
259:                 }
260:         }
261: }