X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fconfig%2Fconfig-manager%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fconfig%2Fmanager%2Fimpl%2Fosgi%2FModuleFactoryBundleTracker.java;h=e89d6c87aa7aaa1cd89f0c6b832c5945630b280b;hp=51443d01e8b7b9b2cbecd878b68fa35dd46827a9;hb=f43b01b81319959b1907e3e04537f5169e7f33d8;hpb=493c4f70a0a315d77927e4c0d90a90acbbcb2897 diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ModuleFactoryBundleTracker.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ModuleFactoryBundleTracker.java index 51443d01e8..e89d6c87aa 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ModuleFactoryBundleTracker.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ModuleFactoryBundleTracker.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * Copyright (c) 2013, 2017 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, @@ -7,27 +7,15 @@ */ package org.opendaylight.controller.config.manager.impl.osgi; -import static java.lang.String.format; import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Charsets; -import com.google.common.base.Stopwatch; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.Multimap; import com.google.common.io.Resources; -import com.google.common.util.concurrent.Uninterruptibles; import java.io.IOException; import java.net.URL; -import java.util.AbstractMap; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Map; -import java.util.Map.Entry; -import java.util.concurrent.TimeUnit; -import javax.annotation.concurrent.GuardedBy; +import java.nio.charset.StandardCharsets; import org.opendaylight.controller.config.spi.ModuleFactory; import org.osgi.framework.Bundle; -import org.osgi.framework.BundleContext; import org.osgi.framework.BundleEvent; +import org.osgi.framework.ServiceRegistration; import org.osgi.util.tracker.BundleTrackerCustomizer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,78 +26,52 @@ import org.slf4j.LoggerFactory; * line should contain an implementation of ModuleFactory interface. Creates new * instance with default constructor and registers it into OSGi service * registry. There is no need for listening for implementing removedBundle as - * the services are unregistered automatically. - * Code based on http://www.toedter.com/blog/?p=236 + * the services are unregistered automatically. Code based on + * http://www.toedter.com/blog/?p=236 */ -public class ModuleFactoryBundleTracker implements BundleTrackerCustomizer { - private static final Logger LOG = LoggerFactory.getLogger(ModuleFactoryBundleTracker.class); - private static final long BUNDLE_CONTEXT_TIMEOUT = TimeUnit.MILLISECONDS.convert(60, TimeUnit.SECONDS); - +public class ModuleFactoryBundleTracker implements BundleTrackerCustomizer { private final BlankTransactionServiceTracker blankTransactionServiceTracker; + private static final Logger LOG = LoggerFactory.getLogger(ModuleFactoryBundleTracker.class); - @GuardedBy(value = "bundleModuleFactoryMap") - private final Multimap bundleModuleFactoryMap = HashMultimap.create(); - - public ModuleFactoryBundleTracker(BlankTransactionServiceTracker blankTransactionServiceTracker) { + public ModuleFactoryBundleTracker(final BlankTransactionServiceTracker blankTransactionServiceTracker) { this.blankTransactionServiceTracker = blankTransactionServiceTracker; } @Override - public Object addingBundle(Bundle bundle, BundleEvent event) { + public Boolean addingBundle(final Bundle bundle, final BundleEvent event) { URL resource = bundle.getEntry("META-INF/services/" + ModuleFactory.class.getName()); - LOG.trace("Got addingBundle event of bundle {}, resource {}, event {}", - bundle, resource, event); + LOG.trace("Got addingBundle event of bundle {}, resource {}, event {}", bundle, resource, event); if (resource != null) { try { - for (String factoryClassName : Resources.readLines(resource, Charsets.UTF_8)) { - Entry moduleFactoryEntry = registerFactory(factoryClassName, bundle); - synchronized (bundleModuleFactoryMap) { - bundleModuleFactoryMap.put(new BundleKey(moduleFactoryEntry.getValue()), - moduleFactoryEntry.getKey()); - } + for (String factoryClassName : Resources.readLines(resource, StandardCharsets.UTF_8)) { + registerFactory(factoryClassName, bundle); } - } catch (IOException e) { + + return Boolean.TRUE; + } catch (final IOException e) { LOG.error("Error while reading {}", resource, e); throw new RuntimeException(e); } } - return bundle; + + return Boolean.FALSE; } @Override - public void modifiedBundle(Bundle bundle, BundleEvent event, Object object) { + public void modifiedBundle(final Bundle bundle, final BundleEvent event, final Boolean hasFactory) { // NOOP } @Override - public void removedBundle(Bundle bundle, BundleEvent event, Object object) { - bundleModuleFactoryMap.removeAll(new BundleKey(bundle)); - - // workaround for service tracker not getting removed service event - blankTransactionServiceTracker.blankTransaction(); - } - - public Collection> getModuleFactoryEntries() { - Collection> entries; - synchronized (bundleModuleFactoryMap) { - entries = new ArrayList<>(bundleModuleFactoryMap.entries()); + public void removedBundle(final Bundle bundle, final BundleEvent event, final Boolean hasFactory) { + if (hasFactory) { + // workaround for service tracker not getting removed service event + blankTransactionServiceTracker.blankTransactionSync(); } - - Collection> result = new ArrayList<>(entries.size()); - for(Entry entry: entries) { - BundleContext context = entry.getKey().getBundleContext(); - if(context == null) { - LOG.warn("Bundle context for {} ModuleFactory not found", entry.getValue()); - } else { - result.add(new AbstractMap.SimpleImmutableEntry<>(entry.getValue(), context)); - } - } - - return result; } @VisibleForTesting - protected static Map.Entry registerFactory(String factoryClassName, Bundle bundle) { + protected static ServiceRegistration registerFactory(final String factoryClassName, final Bundle bundle) { String errorMessage; Exception ex = null; try { @@ -117,84 +79,32 @@ public class ModuleFactoryBundleTracker implements BundleTrackerCustomizer((ModuleFactory)clazz.newInstance(), bundle); - } catch (InstantiationException e) { - errorMessage = logMessage( - "Could not instantiate {} in bundle {}, reason {}", - factoryClassName, bundle, e); + return bundle.getBundleContext().registerService(ModuleFactory.class.getName(), clazz.newInstance(), + null); + } catch (final InstantiationException e) { + errorMessage = logMessage("Could not instantiate {} in bundle {}, reason {}", factoryClassName, + bundle, e); ex = e; - } catch (IllegalAccessException e) { - errorMessage = logMessage( - "Illegal access during instantiation of class {} in bundle {}, reason {}", + } catch (final IllegalAccessException e) { + errorMessage = logMessage("Illegal access during instantiation of class {} in bundle {}, reason {}", factoryClassName, bundle, e); ex = e; - } catch (RuntimeException e) { - errorMessage = logMessage( - "Unexpected exception during instantiation of class {} in bundle {}, reason {}", - clazz, bundle.getBundleContext(), e); - ex = e; } } else { - errorMessage = logMessage( - "Class {} does not implement {} in bundle {}", clazz, - ModuleFactory.class, bundle); + errorMessage = logMessage("Class {} does not implement {} in bundle {}", clazz, ModuleFactory.class, + bundle); } - } catch (ClassNotFoundException e) { - errorMessage = logMessage( - "Could not find class {} in bundle {}, reason {}", - factoryClassName, bundle, e); + } catch (final ClassNotFoundException e) { + errorMessage = logMessage("Could not find class {} in bundle {}, reason {}", factoryClassName, bundle, e); ex = e; } throw ex == null ? new IllegalStateException(errorMessage) : new IllegalStateException(errorMessage, ex); } - public static String logMessage(String slfMessage, Object... params) { + public static String logMessage(final String slfMessage, final Object... params) { LOG.info(slfMessage, params); String formatMessage = slfMessage.replaceAll("\\{\\}", "%s"); - return format(formatMessage, params); - } - - private static class BundleKey { - Bundle bundle; - BundleContext bundleContext; - - public BundleKey(Bundle bundle) { - this.bundle = bundle; - } - - BundleContext getBundleContext() { - if(bundleContext != null) { - return bundleContext; - } - - // If the bundle isn't activated yet, it may not have a BundleContext yet so busy wait for it. - Stopwatch timer = Stopwatch.createStarted(); - while(timer.elapsed(TimeUnit.MILLISECONDS) <= BUNDLE_CONTEXT_TIMEOUT) { - bundleContext = bundle.getBundleContext(); - if(bundleContext != null) { - return bundleContext; - } - - Uninterruptibles.sleepUninterruptibly(10, TimeUnit.MILLISECONDS); - } - - return null; - } - - @Override - public int hashCode() { - return (int) bundle.getBundleId(); - } - - @Override - public boolean equals(Object obj) { - if (getClass() != obj.getClass()) { - return false; - } - BundleKey other = (BundleKey) obj; - return bundle.getBundleId() == other.bundle.getBundleId(); - } + return String.format(formatMessage, params); } }