*/
package org.opendaylight.controller.config.yang.protocol.framework;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.ObjectName;
-
import org.junit.Before;
import org.junit.Test;
import org.opendaylight.controller.config.api.ConflictingVersionException;
import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
import org.opendaylight.controller.config.yang.netty.eventexecutor.GlobalEventExecutorModuleFactory;
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.ObjectName;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
public class NeverReconnectStrategyModuleTest extends AbstractConfigTest {
private static final String INSTANCE_NAME = "never-reconect-strategy-factory-impl";
@Before
public void setUp() throws Exception {
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,
new NeverReconnectStrategyFactoryModuleFactory(), new GlobalEventExecutorModuleFactory()));
}
@Before
public void setUp() throws Exception {
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,
new ReconnectImmediatelyStrategyFactoryModuleFactory(), new GlobalEventExecutorModuleFactory()));
}
*/
package org.opendaylight.controller.config.yang.protocol.framework;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.math.BigDecimal;
-
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.ObjectName;
-
import org.junit.Before;
import org.junit.Test;
import org.opendaylight.controller.config.api.ConflictingVersionException;
import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
import org.opendaylight.controller.config.yang.netty.eventexecutor.GlobalEventExecutorModuleFactory;
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.ObjectName;
+import java.math.BigDecimal;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
public class TimedReconnectStrategyModuleTest extends AbstractConfigTest {
private static final String INSTANCE_NAME = "timed-reconect-stategy-facotry-impl";
@Before
public void setUp() throws Exception {
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,
new TimedReconnectStrategyFactoryModuleFactory(), new GlobalEventExecutorModuleFactory()));
}
import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
+/**
+ * Interface exposing some internal state on top of ServiceReferenceReadableRegistry. This will
+ * not be exposed via JMX.
+ */
public interface CloseableServiceReferenceReadableRegistry extends AutoCloseable, ServiceReferenceReadableRegistry {
-
void close();
}
import org.opendaylight.controller.config.api.ConflictingVersionException;
import org.opendaylight.controller.config.api.ModuleIdentifier;
import org.opendaylight.controller.config.api.RuntimeBeanRegistratorAwareModule;
-import org.opendaylight.controller.config.api.ServiceReferenceWritableRegistry;
import org.opendaylight.controller.config.api.ValidationException;
+import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation;
import org.opendaylight.controller.config.api.jmx.CommitStatus;
import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
import org.opendaylight.controller.config.manager.impl.dependencyresolver.DestroyedModule;
}
};
- Map<String, Map.Entry<ModuleFactory, BundleContext>> allCurrentFactories = Collections.unmodifiableMap(
+ Map<String, Map.Entry<ModuleFactory, BundleContext>> allCurrentFactories = new HashMap<>(
resolver.getAllFactories());
+ // add all factories that disappeared from SR but are still committed
+ for (ModuleInternalInfo moduleInternalInfo : currentConfig.getEntries()) {
+ String name = moduleInternalInfo.getModuleFactory().getImplementationName();
+ if (allCurrentFactories.containsKey(name) == false) {
+ logger.trace("Factory {} not found in SR, using reference from previous commit", name);
+ allCurrentFactories.put(name,
+ Maps.immutableEntry(moduleInternalInfo.getModuleFactory(), moduleInternalInfo.getBundleContext()));
+ }
+ }
+ allCurrentFactories = Collections.unmodifiableMap(allCurrentFactories);
+
// closed by transaction controller
ConfigTransactionLookupRegistry txLookupRegistry = new ConfigTransactionLookupRegistry(new TransactionIdentifier(
transactionName), factory, allCurrentFactories);
- ServiceReferenceWritableRegistry writableRegistry = ServiceReferenceRegistryImpl.createSRWritableRegistry(
+ SearchableServiceReferenceWritableRegistry writableRegistry = ServiceReferenceRegistryImpl.createSRWritableRegistry(
readableSRRegistry, txLookupRegistry, allCurrentFactories);
ConfigTransactionControllerInternal transactionController = new ConfigTransactionControllerImpl(
// non recoverable from here:
try {
return secondPhaseCommit(configTransactionController, commitInfo, configTransactionControllerEntry.getValue());
- } catch (Throwable t) { // some libs throw Errors: e.g.
+ } catch (Error | RuntimeException t) { // some libs throw Errors: e.g.
// javax.xml.ws.spi.FactoryFinder$ConfigurationError
isHealthy = false;
logger.error("Configuration Transaction failed on 2PC, server is unhealthy", t);
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
- } else if (t instanceof Error) {
- throw (Error) t;
} else {
- throw new RuntimeException(t);
+ throw (Error) t;
}
}
}
// register to JMX
try {
- newModuleJMXRegistrator.registerMBean(newReadableConfigBean,
- primaryReadOnlyON);
+ newModuleJMXRegistrator.registerMBean(newReadableConfigBean, primaryReadOnlyON);
} catch (InstanceAlreadyExistsException e) {
- throw new IllegalStateException(e);
+ throw new IllegalStateException("Possible code error, already registered:" + primaryReadOnlyON,e);
}
- // register to OSGi
+ // register services to OSGi
+ Map<String, ServiceInterfaceAnnotation> annotationMapping = configTransactionController.getWritableRegistry().findServiceInterfaces(moduleIdentifier);
+ BundleContext bc = configTransactionController.getModuleFactoryBundleContext(
+ entry.getModuleFactory().getImplementationName());
if (osgiRegistration == null) {
- ModuleFactory moduleFactory = entry.getModuleFactory();
- if (moduleFactory != null) {
- BundleContext bc = configTransactionController.
- getModuleFactoryBundleContext(moduleFactory.getImplementationName());
- osgiRegistration = beanToOsgiServiceManager.registerToOsgi(realModule.getClass(),
- newReadableConfigBean.getInstance(), entry.getIdentifier(), bc);
- } else {
- throw new NullPointerException(entry.getIdentifier().getFactoryName() + " ModuleFactory not found.");
- }
-
+ osgiRegistration = beanToOsgiServiceManager.registerToOsgi(
+ newReadableConfigBean.getInstance(), moduleIdentifier, bc, annotationMapping);
+ } else {
+ osgiRegistration.updateRegistrations(annotationMapping, bc, instance);
}
RootRuntimeBeanRegistratorImpl runtimeBeanRegistrator = runtimeRegistrators
ModuleInternalInfo newInfo = new ModuleInternalInfo(
entry.getIdentifier(), newReadableConfigBean, osgiRegistration,
runtimeBeanRegistrator, newModuleJMXRegistrator,
- orderingIdx, entry.isDefaultBean());
+ orderingIdx, entry.isDefaultBean(), entry.getModuleFactory(), entry.getBundleContext());
newConfigEntries.put(realModule, newInfo);
orderingIdx++;
*/
package org.opendaylight.controller.config.manager.impl;
+import static java.lang.String.format;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.GuardedBy;
+import javax.management.DynamicMBean;
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
import org.opendaylight.controller.config.api.DependencyResolver;
import org.opendaylight.controller.config.api.ModuleIdentifier;
-import org.opendaylight.controller.config.api.ServiceReferenceWritableRegistry;
import org.opendaylight.controller.config.api.ValidationException;
import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
import org.opendaylight.controller.config.manager.impl.dependencyresolver.DependencyResolverManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.annotation.Nullable;
-import javax.annotation.concurrent.GuardedBy;
-import javax.management.DynamicMBean;
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.InstanceNotFoundException;
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicBoolean;
-
import static com.google.common.base.Preconditions.checkNotNull;
-import static java.lang.String.format;
-
/**
* This is a JMX bean representing current transaction. It contains
* transaction identifier, unique version and parent version for
private final boolean blankTransaction;
@GuardedBy("this")
- private final ServiceReferenceWritableRegistry writableSRRegistry;
+ private final SearchableServiceReferenceWritableRegistry writableSRRegistry;
public ConfigTransactionControllerImpl(ConfigTransactionLookupRegistry txLookupRegistry,
long parentVersion, CodecRegistry codecRegistry, long currentVersion,
Map<String, Entry<ModuleFactory, BundleContext>> currentlyRegisteredFactories,
MBeanServer transactionsMBeanServer, MBeanServer configMBeanServer,
- boolean blankTransaction, ServiceReferenceWritableRegistry writableSRRegistry) {
+ boolean blankTransaction, SearchableServiceReferenceWritableRegistry writableSRRegistry) {
this.txLookupRegistry = txLookupRegistry;
String transactionName = txLookupRegistry.getTransactionIdentifier().getName();
this.controllerON = ObjectNameUtil.createTransactionControllerON(transactionName);
}
// add default modules
for (ModuleFactory moduleFactory : toBeAdded) {
+ BundleContext bundleContext = getModuleFactoryBundleContext(moduleFactory.getImplementationName());
Set<? extends Module> defaultModules = moduleFactory.getDefaultModules(dependencyResolverManager,
- getModuleFactoryBundleContext(moduleFactory.getImplementationName()));
+ bundleContext);
for (Module module : defaultModules) {
// ensure default module to be registered to jmx even if its module factory does not use dependencyResolverFactory
DependencyResolver dependencyResolver = dependencyResolverManager.getOrCreate(module.getIdentifier());
try {
boolean defaultBean = true;
- putConfigBeanToJMXAndInternalMaps(module.getIdentifier(), module, moduleFactory, null, dependencyResolver, defaultBean);
+ putConfigBeanToJMXAndInternalMaps(module.getIdentifier(), module, moduleFactory, null,
+ dependencyResolver, defaultBean, bundleContext);
} catch (InstanceAlreadyExistsException e) {
throw new IllegalStateException(e);
}
}
- private synchronized void copyExistingModule(
- ModuleInternalInfo oldConfigBeanInfo)
- throws InstanceAlreadyExistsException {
+ private synchronized void copyExistingModule(ModuleInternalInfo oldConfigBeanInfo) throws InstanceAlreadyExistsException {
+
transactionStatus.checkNotCommitStarted();
transactionStatus.checkNotAborted();
ModuleIdentifier moduleIdentifier = oldConfigBeanInfo.getIdentifier();
dependencyResolverManager.assertNotExists(moduleIdentifier);
- ModuleFactory moduleFactory = factoriesHolder
- .findByModuleName(moduleIdentifier.getFactoryName());
+ ModuleFactory moduleFactory;
+ BundleContext bc;
+ try {
+ moduleFactory = factoriesHolder.findByModuleName(moduleIdentifier.getFactoryName());
+ bc = getModuleFactoryBundleContext(moduleFactory.getImplementationName());
+ } catch (InstanceNotFoundException e) {
+ throw new IllegalStateException(e);
+ }
Module module;
DependencyResolver dependencyResolver = dependencyResolverManager.getOrCreate(moduleIdentifier);
try {
- BundleContext bc = getModuleFactoryBundleContext(moduleFactory.getImplementationName());
+
module = moduleFactory.createModule(
moduleIdentifier.getInstanceName(), dependencyResolver,
oldConfigBeanInfo.getReadableModule(), bc);
oldConfigBeanInfo, moduleFactory), e);
}
putConfigBeanToJMXAndInternalMaps(moduleIdentifier, module, moduleFactory, oldConfigBeanInfo, dependencyResolver,
- oldConfigBeanInfo.isDefaultBean());
+ oldConfigBeanInfo.isDefaultBean(), bc);
}
@Override
dependencyResolverManager.assertNotExists(moduleIdentifier);
// find factory
- ModuleFactory moduleFactory = factoriesHolder.findByModuleName(factoryName);
+ ModuleFactory moduleFactory;
+ try {
+ moduleFactory = factoriesHolder.findByModuleName(factoryName);
+ } catch (InstanceNotFoundException e) {
+ throw new IllegalArgumentException(e);
+ }
DependencyResolver dependencyResolver = dependencyResolverManager.getOrCreate(moduleIdentifier);
+ BundleContext bundleContext = getModuleFactoryBundleContext(moduleFactory.getImplementationName());
Module module = moduleFactory.createModule(instanceName, dependencyResolver,
- getModuleFactoryBundleContext(moduleFactory.getImplementationName()));
+ bundleContext);
boolean defaultBean = false;
return putConfigBeanToJMXAndInternalMaps(moduleIdentifier, module,
- moduleFactory, null, dependencyResolver, defaultBean);
+ moduleFactory, null, dependencyResolver, defaultBean, bundleContext);
}
private synchronized ObjectName putConfigBeanToJMXAndInternalMaps(
ModuleIdentifier moduleIdentifier, Module module,
ModuleFactory moduleFactory,
- @Nullable ModuleInternalInfo maybeOldConfigBeanInfo, DependencyResolver dependencyResolver, boolean isDefaultBean)
+ @Nullable ModuleInternalInfo maybeOldConfigBeanInfo, DependencyResolver dependencyResolver,
+ boolean isDefaultBean, BundleContext bundleContext)
throws InstanceAlreadyExistsException {
logger.debug("Adding module {} to transaction {}", moduleIdentifier, this);
dependencyResolverManager.put(
moduleIdentifier, module, moduleFactory,
- maybeOldConfigBeanInfo, transactionModuleJMXRegistration, isDefaultBean);
+ maybeOldConfigBeanInfo, transactionModuleJMXRegistration, isDefaultBean, bundleContext);
return writableON;
}
logger.debug("Destroying module {} in transaction {}", moduleIdentifier, this);
transactionStatus.checkNotAborted();
+ ModuleInternalTransactionalInfo found = dependencyResolverManager.findModuleInternalTransactionalInfo(moduleIdentifier);
if (blankTransaction == false) {
- ModuleInternalTransactionalInfo found =
- dependencyResolverManager.findModuleInternalTransactionalInfo(moduleIdentifier);
+
if (found.isDefaultBean()) {
logger.warn("Warning: removing default bean. This will be forbidden in next version of config-subsystem");
}
}
// first remove refNames, it checks for objectname existence
+
try {
writableSRRegistry.removeServiceReferences(
ObjectNameUtil.createTransactionModuleON(getTransactionName(), moduleIdentifier));
}
@Override
- public ServiceReferenceWritableRegistry getWritableRegistry() {
+ public SearchableServiceReferenceWritableRegistry getWritableRegistry() {
return writableSRRegistry;
}
*/
package org.opendaylight.controller.config.manager.impl;
-import java.util.Collection;
-import java.util.List;
-
-import javax.management.ObjectName;
-
import org.opendaylight.controller.config.api.ModuleIdentifier;
-import org.opendaylight.controller.config.api.ServiceReferenceWritableRegistry;
import org.opendaylight.controller.config.api.ValidationException;
import org.opendaylight.controller.config.spi.ModuleFactory;
import org.osgi.framework.BundleContext;
+import javax.management.ObjectName;
+import java.util.Collection;
+import java.util.List;
+
/**
* Defines contract between {@link ConfigTransactionControllerImpl} (producer)
* and {@link ConfigRegistryImpl} (consumer).
BundleContext getModuleFactoryBundleContext(String factoryName);
- ServiceReferenceWritableRegistry getWritableRegistry();
+ SearchableServiceReferenceWritableRegistry getWritableRegistry();
TransactionIdentifier getTransactionIdentifier();
import javax.annotation.Nullable;
import javax.annotation.concurrent.GuardedBy;
+import java.util.Deque;
+import java.util.LinkedList;
import java.util.concurrent.TimeUnit;
public class DeadlockMonitor implements AutoCloseable {
private final TransactionIdentifier transactionIdentifier;
private final DeadlockMonitorRunnable thread;
@GuardedBy("this")
- private ModuleIdentifierWithNanos moduleIdentifierWithNanos = new ModuleIdentifierWithNanos();
+ private final Deque<ModuleIdentifierWithNanos> moduleIdentifierWithNanosStack = new LinkedList<>();
+ @GuardedBy("this")
+ private ModuleIdentifierWithNanos top = ModuleIdentifierWithNanos.EMPTY;
public DeadlockMonitor(TransactionIdentifier transactionIdentifier) {
this.transactionIdentifier = transactionIdentifier;
}
public synchronized void setCurrentlyInstantiatedModule(ModuleIdentifier currentlyInstantiatedModule) {
- this.moduleIdentifierWithNanos = new ModuleIdentifierWithNanos(currentlyInstantiatedModule);
+
+ boolean popping = currentlyInstantiatedModule == null;
+ if (popping) {
+ moduleIdentifierWithNanosStack.pop();
+ if (moduleIdentifierWithNanosStack.isEmpty()) {
+ top = ModuleIdentifierWithNanos.EMPTY;
+ } else {
+ top = moduleIdentifierWithNanosStack.peekLast();
+ }
+ } else {
+ ModuleIdentifierWithNanos current = new ModuleIdentifierWithNanos(currentlyInstantiatedModule);
+ moduleIdentifierWithNanosStack.push(current);
+ top = current;
+ }
+ logger.trace("setCurrentlyInstantiatedModule {}, top {}", currentlyInstantiatedModule, top);
}
public boolean isAlive() {
public void run() {
ModuleIdentifierWithNanos old = new ModuleIdentifierWithNanos(); // null moduleId
while (this.isInterrupted() == false) {
- ModuleIdentifierWithNanos copy = new ModuleIdentifierWithNanos(DeadlockMonitor.this.moduleIdentifierWithNanos);
- if (old.moduleIdentifier == null) {
+ ModuleIdentifierWithNanos copy = new ModuleIdentifierWithNanos(DeadlockMonitor.this.top);
+ if (old.moduleIdentifier == null || old.equals(copy) == false) {
// started
old = copy;
- } else if (old.moduleIdentifier != null && old.equals(copy)) {
+ } else {
// is the getInstance() running longer than WARN_AFTER_MILLIS ?
long runningTime = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - copy.nanoTime);
if (runningTime > WARN_AFTER_MILLIS) {
}
}
- private class ModuleIdentifierWithNanos {
+
+
+
+ private static class ModuleIdentifierWithNanos {
+ private static ModuleIdentifierWithNanos EMPTY = new ModuleIdentifierWithNanos();
@Nullable
private final ModuleIdentifier moduleIdentifier;
+
private final long nanoTime;
private ModuleIdentifierWithNanos() {
- moduleIdentifier = null;
- nanoTime = System.nanoTime();
+ this((ModuleIdentifier)null);
}
private ModuleIdentifierWithNanos(ModuleIdentifier moduleIdentifier) {
result = 31 * result + (int) (nanoTime ^ (nanoTime >>> 32));
return result;
}
+
+ @Override
+ public String toString() {
+ return "ModuleIdentifierWithNanos{" +
+ moduleIdentifier +
+ '}';
+ }
}
}
import org.opendaylight.controller.config.manager.impl.jmx.ModuleJMXRegistrator;
import org.opendaylight.controller.config.manager.impl.jmx.RootRuntimeBeanRegistratorImpl;
import org.opendaylight.controller.config.manager.impl.osgi.BeanToOsgiServiceManager.OsgiRegistration;
+import org.opendaylight.controller.config.spi.ModuleFactory;
import org.opendaylight.yangtools.concepts.Identifiable;
+import org.osgi.framework.BundleContext;
/**
* Provides metadata about Module from controller to registry.
private final ModuleJMXRegistrator moduleJMXRegistrator;
private final int orderingIdx;
private final boolean isDefaultBean;
+ private final ModuleFactory moduleFactory;
+ private final BundleContext bundleContext;
public ModuleInternalInfo(ModuleIdentifier name,
@Nullable DynamicReadableWrapper readableModule,
OsgiRegistration osgiRegistration,
RootRuntimeBeanRegistratorImpl runtimeBeanRegistrator,
ModuleJMXRegistrator moduleJMXRegistrator, int orderingIdx,
- boolean isDefaultBean) {
+ boolean isDefaultBean, ModuleFactory moduleFactory, BundleContext bundleContext) {
if (osgiRegistration == null) {
throw new IllegalArgumentException(
this.moduleJMXRegistrator = moduleJMXRegistrator;
this.orderingIdx = orderingIdx;
this.isDefaultBean = isDefaultBean;
+ this.moduleFactory = moduleFactory;
+ this.bundleContext = bundleContext;
}
public DynamicReadableWrapper getReadableModule() {
public boolean isDefaultBean() {
return isDefaultBean;
}
+
+ public ModuleFactory getModuleFactory() {
+ return moduleFactory;
+ }
+
+ public BundleContext getBundleContext() {
+ return bundleContext;
+ }
}
--- /dev/null
+/*
+ * Copyright (c) 2013 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,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.config.manager.impl;
+
+import java.util.Map;
+import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.opendaylight.controller.config.api.ServiceReferenceWritableRegistry;
+import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation;
+
+public interface SearchableServiceReferenceWritableRegistry extends ServiceReferenceWritableRegistry {
+ /**
+ * Return mapping between service ref names and service interface annotation for given
+ * module.
+ *
+ * @throws java.lang.IllegalArgumentException if any of service qNames is not found
+ * @throws java.lang.NullPointerException if parameter is null
+ */
+ Map<String /* service ref */, ServiceInterfaceAnnotation> findServiceInterfaces(ModuleIdentifier moduleIdentifier);
+
+}
*/
package org.opendaylight.controller.config.manager.impl;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.InstanceNotFoundException;
+import javax.management.ObjectName;
import org.opendaylight.controller.config.api.LookupRegistry;
import org.opendaylight.controller.config.api.ModuleIdentifier;
import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.InstanceNotFoundException;
-import javax.management.ObjectName;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceReadableRegistry, ServiceReferenceWritableRegistry {
+public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceReadableRegistry, SearchableServiceReferenceWritableRegistry {
private static final Logger logger = LoggerFactory.getLogger(ServiceReferenceRegistryImpl.class);
private final Map<String, ModuleFactory> factories;
private final ServiceReferenceRegistrator serviceReferenceRegistrator;
// helper method for getting QName of SI from namespace + local name
private final Map<String /* namespace */, Map<String /* local name */, ServiceInterfaceAnnotation>> namespacesToAnnotations;
+ private final Map<String /* service qName */, ServiceInterfaceAnnotation> serviceQNamesToAnnotations;
// all Service Interface qNames for sanity checking
private final Set<String /* qName */> allQNames;
+ Map<ModuleIdentifier, Map<String /* service ref name */, ServiceInterfaceAnnotation >> modulesToServiceRef = new HashMap<>();
+
// actual reference database
private final Map<ServiceReference, ModuleIdentifier> refNames = new HashMap<>();
/**
* Static constructor for transaction controller. Take current state as seen by config registry, allow writing new data.
*/
- public static ServiceReferenceWritableRegistry createSRWritableRegistry(ServiceReferenceReadableRegistry oldReadableRegistry,
+ public static SearchableServiceReferenceWritableRegistry createSRWritableRegistry(ServiceReferenceReadableRegistry oldReadableRegistry,
ConfigTransactionLookupRegistry txLookupRegistry,
Map<String, Map.Entry<ModuleFactory, BundleContext>> currentlyRegisteredFactories) {
Map<String, Set<String /* QName */>> modifiableFactoryNamesToQNames = new HashMap<>();
Set<ServiceInterfaceAnnotation> allAnnotations = new HashSet<>();
Set<String /* qName */> allQNames = new HashSet<>();
+
+
for (Entry<String, ModuleFactory> entry : factories.entrySet()) {
if (entry.getKey().equals(entry.getValue().getImplementationName()) == false) {
logger.error("Possible error in code: Mismatch between supplied and actual name of {}", entry);
throw new IllegalArgumentException("Possible error in code: Mismatch between supplied and actual name of " + entry);
}
Set<ServiceInterfaceAnnotation> siAnnotations = InterfacesHelper.getServiceInterfaceAnnotations(entry.getValue());
- Set<String> qNames = new HashSet<>();
- for (ServiceInterfaceAnnotation sia: siAnnotations) {
- qNames.add(sia.value());
- }
+ Set<String> qNames = InterfacesHelper.getQNames(siAnnotations);
allAnnotations.addAll(siAnnotations);
allQNames.addAll(qNames);
modifiableFactoryNamesToQNames.put(entry.getKey(), Collections.unmodifiableSet(qNames));
// fill namespacesToAnnotations
Map<String /* namespace */, Map<String /* localName */, ServiceInterfaceAnnotation>> modifiableNamespacesToAnnotations =
new HashMap<>();
+ Map<String /* service qName*/, ServiceInterfaceAnnotation> modifiableServiceQNamesToAnnotations = new HashMap<>();
for (ServiceInterfaceAnnotation sia : allAnnotations) {
Map<String, ServiceInterfaceAnnotation> ofNamespace = modifiableNamespacesToAnnotations.get(sia.namespace());
if (ofNamespace == null) {
throw new IllegalArgumentException("Conflict between local names in " + sia.namespace() + " : " + sia.localName());
}
ofNamespace.put(sia.localName(), sia);
+ modifiableServiceQNamesToAnnotations.put(sia.value(), sia);
}
this.namespacesToAnnotations = Collections.unmodifiableMap(modifiableNamespacesToAnnotations);
- // copy refNames
+ this.serviceQNamesToAnnotations = Collections.unmodifiableMap(modifiableServiceQNamesToAnnotations);
logger.trace("factoryNamesToQNames:{}", this.factoryNamesToQNames);
}
+ @Override
+ public Map<String /* service ref */, ServiceInterfaceAnnotation> findServiceInterfaces(ModuleIdentifier moduleIdentifier) {
+ Map<String, ServiceInterfaceAnnotation> result = modulesToServiceRef.get(moduleIdentifier);
+ if (result == null) {
+ return Collections.emptyMap();
+ }
+ return Collections.unmodifiableMap(result);
+ }
@Override
public synchronized Set<String> lookupServiceInterfaceNames(ObjectName objectName) throws InstanceNotFoundException {
public synchronized Map<String /* serviceInterfaceName */, Map<String/* refName */, ObjectName>> getServiceMapping() {
Map<String /* serviceInterfaceName */, Map<String/* refName */, ObjectName>> result = new HashMap<>();
for (Entry<ServiceReference, ModuleIdentifier> entry: refNames.entrySet()) {
- String qName = entry.getKey().getServiceInterfaceName();
+ String qName = entry.getKey().getServiceInterfaceQName();
Map<String /* refName */, ObjectName> innerMap = result.get(qName);
if (innerMap == null) {
innerMap = new HashMap<>();
throw new IllegalStateException("Possible error in code: cannot find annotations of existing factory " + moduleIdentifier.getFactoryName());
}
// supplied serviceInterfaceName must exist in this collection
- if (serviceInterfaceQNames.contains(serviceReference.getServiceInterfaceName()) == false) {
- logger.error("Cannot find qName {} with factory name {}, found {}", serviceReference.getServiceInterfaceName(), moduleIdentifier.getFactoryName(), serviceInterfaceQNames);
- throw new IllegalArgumentException("Cannot find service interface " + serviceReference.getServiceInterfaceName() + " within factory " + moduleIdentifier.getFactoryName());
+ if (serviceInterfaceQNames.contains(serviceReference.getServiceInterfaceQName()) == false) {
+ logger.error("Cannot find qName {} with factory name {}, found {}", serviceReference.getServiceInterfaceQName(), moduleIdentifier.getFactoryName(), serviceInterfaceQNames);
+ throw new IllegalArgumentException("Cannot find service interface " + serviceReference.getServiceInterfaceQName() + " within factory " + moduleIdentifier.getFactoryName());
}
}
// save to refNames
refNames.put(serviceReference, moduleIdentifier);
+ Map<String, ServiceInterfaceAnnotation> refNamesToAnnotations = modulesToServiceRef.get(moduleIdentifier);
+ if (refNamesToAnnotations == null){
+ refNamesToAnnotations = new HashMap<>();
+ modulesToServiceRef.put(moduleIdentifier, refNamesToAnnotations);
+ }
+
+ ServiceInterfaceAnnotation annotation = serviceQNamesToAnnotations.get(serviceReference.getServiceInterfaceQName());
+ checkNotNull(annotation, "Possible error in code, cannot find annotation for " + serviceReference);
+ refNamesToAnnotations.put(serviceReference.getRefName(), annotation);
return result;
}
private ObjectName getServiceON(ServiceReference serviceReference) {
if (writable) {
return ObjectNameUtil.createTransactionServiceON(serviceReferenceRegistrator.getNullableTransactionName(),
- serviceReference.getServiceInterfaceName(), serviceReference.getRefName());
+ serviceReference.getServiceInterfaceQName(), serviceReference.getRefName());
} else {
- return ObjectNameUtil.createReadOnlyServiceON(serviceReference.getServiceInterfaceName(), serviceReference.getRefName());
+ return ObjectNameUtil.createReadOnlyServiceON(serviceReference.getServiceInterfaceQName(), serviceReference.getRefName());
}
}
logger.debug("Removing service reference {} from {}", serviceReference, this);
assertWritable();
// is the qName known?
- if (allQNames.contains(serviceReference.getServiceInterfaceName()) == false) {
- logger.error("Cannot find qname {} in {}", serviceReference.getServiceInterfaceName(), allQNames);
- throw new IllegalArgumentException("Cannot find service interface " + serviceReference.getServiceInterfaceName());
+ if (allQNames.contains(serviceReference.getServiceInterfaceQName()) == false) {
+ logger.error("Cannot find qname {} in {}", serviceReference.getServiceInterfaceQName(), allQNames);
+ throw new IllegalArgumentException("Cannot find service interface " + serviceReference.getServiceInterfaceQName());
}
ModuleIdentifier removed = refNames.remove(serviceReference);
if (removed == null){
- throw new InstanceNotFoundException("Cannot find " + serviceReference.getServiceInterfaceName());
+ throw new InstanceNotFoundException("Cannot find " + serviceReference.getServiceInterfaceQName());
}
Entry<ServiceReferenceMXBeanImpl, ServiceReferenceJMXRegistration> entry = mBeans.remove(serviceReference);
if (entry == null) {
@Override
public synchronized boolean removeServiceReferences(ObjectName moduleObjectName) throws InstanceNotFoundException {
+ lookupRegistry.checkConfigBeanExists(moduleObjectName);
+ String factoryName = ObjectNameUtil.getFactoryName(moduleObjectName);
+ // check that service interface name exist
+ Set<String> serviceInterfaceQNames = factoryNamesToQNames.get(factoryName);
+ return removeServiceReferences(moduleObjectName, serviceInterfaceQNames);
+ }
+
+
+ private boolean removeServiceReferences(ObjectName moduleObjectName, Set<String> qNames) throws InstanceNotFoundException {
+ ObjectNameUtil.checkType(moduleObjectName, ObjectNameUtil.TYPE_MODULE);
assertWritable();
- Set<ServiceReference> serviceReferencesLinkingTo = findServiceReferencesLinkingTo(moduleObjectName);
+ Set<ServiceReference> serviceReferencesLinkingTo = findServiceReferencesLinkingTo(moduleObjectName, qNames);
for (ServiceReference sr : serviceReferencesLinkingTo) {
removeServiceReference(sr);
}
return serviceReferencesLinkingTo.isEmpty() == false;
}
- private synchronized Set<ServiceReference> findServiceReferencesLinkingTo(ObjectName moduleObjectName) throws InstanceNotFoundException {
- lookupRegistry.checkConfigBeanExists(moduleObjectName);
+ private Set<ServiceReference> findServiceReferencesLinkingTo(ObjectName moduleObjectName, Set<String> serviceInterfaceQNames) {
String factoryName = ObjectNameUtil.getFactoryName(moduleObjectName);
- // check that service interface name exist
- Set<String> serviceInterfaceQNames = factoryNamesToQNames.get(factoryName);
if (serviceInterfaceQNames == null) {
- logger.error("Possible error in code: cannot find factoryName {} in {}, object name {}", factoryName, factoryNamesToQNames, moduleObjectName);
+ logger.warn("Possible error in code: cannot find factoryName {} in {}, object name {}", factoryName, factoryNamesToQNames, moduleObjectName);
throw new IllegalStateException("Possible error in code: cannot find annotations of existing factory " + factoryName);
}
String instanceName = ObjectNameUtil.getInstanceName(moduleObjectName);
return result;
}
-
@Override
public String toString() {
return "ServiceReferenceRegistryImpl{" +
*/
package org.opendaylight.controller.config.manager.impl.dependencyresolver;
+import static com.google.common.base.Preconditions.checkState;
+
import com.google.common.reflect.AbstractInvocationHandler;
import com.google.common.reflect.Reflection;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.annotation.concurrent.GuardedBy;
+import javax.management.InstanceAlreadyExistsException;
import org.opendaylight.controller.config.api.DependencyResolver;
import org.opendaylight.controller.config.api.DependencyResolverFactory;
import org.opendaylight.controller.config.api.JmxAttribute;
import org.opendaylight.controller.config.spi.Module;
import org.opendaylight.controller.config.spi.ModuleFactory;
import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry;
-
-import javax.annotation.concurrent.GuardedBy;
-import javax.management.InstanceAlreadyExistsException;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import static com.google.common.base.Preconditions.checkState;
+import org.osgi.framework.BundleContext;
/**
* Holds information about modules being created and destroyed within this
ModuleFactory moduleFactory,
ModuleInternalInfo maybeOldInternalInfo,
TransactionModuleJMXRegistration transactionModuleJMXRegistration,
- boolean isDefaultBean) {
+ boolean isDefaultBean, BundleContext bundleContext) {
transactionStatus.checkNotCommitted();
Class<? extends Module> moduleClass = Module.class;
ModuleInternalTransactionalInfo moduleInternalTransactionalInfo = new ModuleInternalTransactionalInfo(
moduleIdentifier, proxiedModule, moduleFactory,
- maybeOldInternalInfo, transactionModuleJMXRegistration, isDefaultBean, module);
+ maybeOldInternalInfo, transactionModuleJMXRegistration, isDefaultBean, module, bundleContext);
modulesHolder.put(moduleInternalTransactionalInfo);
}
import org.opendaylight.yangtools.concepts.Identifiable;
import javax.annotation.Nullable;
+import org.osgi.framework.BundleContext;
public class ModuleInternalTransactionalInfo implements Identifiable<ModuleIdentifier> {
private final ModuleIdentifier name;
private final ModuleInternalInfo maybeOldInternalInfo;
private final TransactionModuleJMXRegistration transactionModuleJMXRegistration;
private final boolean isDefaultBean;
+ private final BundleContext bundleContext;
public ModuleInternalTransactionalInfo(ModuleIdentifier name, Module proxiedModule,
ModuleFactory moduleFactory,
ModuleInternalInfo maybeOldInternalInfo,
TransactionModuleJMXRegistration transactionModuleJMXRegistration,
- boolean isDefaultBean, Module realModule) {
+ boolean isDefaultBean, Module realModule, BundleContext bundleContext) {
this.name = name;
this.proxiedModule = proxiedModule;
this.moduleFactory = moduleFactory;
this.transactionModuleJMXRegistration = transactionModuleJMXRegistration;
this.isDefaultBean = isDefaultBean;
this.realModule = realModule;
+ this.bundleContext = bundleContext;
}
public Module getRealModule() {
return realModule;
}
+
+ public BundleContext getBundleContext() {
+ return bundleContext;
+ }
}
package org.opendaylight.controller.config.manager.impl.factoriesresolver;
-import org.opendaylight.controller.config.spi.ModuleFactory;
-import org.osgi.framework.BundleContext;
-
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
-import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeSet;
+import javax.management.InstanceNotFoundException;
+import org.opendaylight.controller.config.spi.ModuleFactory;
+import org.osgi.framework.BundleContext;
/**
* Hold sorted ConfigMBeanFactories by their module names. Check that module
* @throws IllegalArgumentException
* if factory is not found
*/
- public ModuleFactory findByModuleName(String moduleName) {
+ public ModuleFactory findByModuleName(String moduleName) throws InstanceNotFoundException {
Map.Entry<ModuleFactory, BundleContext> result = moduleNamesToConfigBeanFactories.get(moduleName);
if (result == null) {
- throw new IllegalArgumentException(
+ throw new InstanceNotFoundException(
"ModuleFactory not found with module name: " + moduleName);
}
return result.getKey();
return moduleFactories;
}
- public Map<String, Entry<ModuleFactory, BundleContext>> getModuleNamesToConfigBeanFactories() {
- return moduleNamesToConfigBeanFactories;
- }
}
this.refName = refName;
}
- public String getServiceInterfaceName() {
+ public String getServiceInterfaceQName() {
return serviceInterfaceName;
}
result = 31 * result + refName.hashCode();
return result;
}
+
+ @Override
+ public String toString() {
+ return "ServiceReference{" +
+ "serviceInterfaceName='" + serviceInterfaceName + '\'' +
+ ", refName='" + refName + '\'' +
+ '}';
+ }
}
*/
package org.opendaylight.controller.config.manager.impl.osgi;
-import org.opendaylight.controller.config.api.ModuleIdentifier;
-import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation;
-import org.opendaylight.controller.config.manager.impl.util.InterfacesHelper;
-import org.opendaylight.controller.config.spi.Module;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
+import static com.google.common.base.Preconditions.checkState;
import java.util.Dictionary;
import java.util.HashSet;
import java.util.Hashtable;
+import java.util.Map;
+import java.util.Map.Entry;
import java.util.Set;
+import javax.annotation.concurrent.GuardedBy;
+import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Registers instantiated beans as OSGi services and unregisters these services
* if beans are destroyed.
*/
public class BeanToOsgiServiceManager {
- // name of properties submitted to osgi
- static final String INSTANCE_NAME_OSGI_PROP = "instanceName";
- static final String IMPLEMENTATION_NAME_OSGI_PROP = "implementationName";
+ private static final String SERVICE_NAME_OSGI_PROP = "name";
/**
* To be called for every created, reconfigured and recreated config bean.
* It is expected that before using this method OSGi service registry will
* be cleaned from previous registrations.
*/
- public OsgiRegistration registerToOsgi(
- Class<? extends Module> configBeanClass, AutoCloseable instance,
- ModuleIdentifier moduleIdentifier, BundleContext bundleContext) {
- try {
- final Set<Class<?>> configuresInterfaces = InterfacesHelper
- .getOsgiRegistrationTypes(configBeanClass);
- checkInstanceImplementing(instance, configuresInterfaces);
-
- // bundleContext.registerService blows up with empty 'clazzes'
- if (configuresInterfaces.isEmpty() == false) {
- final Dictionary<String, ?> propertiesForOsgi = getPropertiesForOsgi(moduleIdentifier);
- final ServiceRegistration<?> serviceRegistration = bundleContext
- .registerService(classesToNames(configuresInterfaces), instance, propertiesForOsgi);
- return new OsgiRegistration(serviceRegistration);
- } else {
- return new OsgiRegistration();
- }
- } catch (IllegalStateException e) {
- throw new IllegalStateException(
- "Error while registering instance into OSGi Service Registry: "
- + moduleIdentifier, e);
- }
+ public OsgiRegistration registerToOsgi(AutoCloseable instance, ModuleIdentifier moduleIdentifier,
+ BundleContext bundleContext,
+ Map<String, ServiceInterfaceAnnotation> serviceNamesToAnnotations) {
+ return new OsgiRegistration(instance, moduleIdentifier, bundleContext, serviceNamesToAnnotations);
}
- private static String[] classesToNames(Set<Class<?>> cfgs) {
- String[] result = new String[cfgs.size()];
- int i = 0;
- for (Class<?> cfg : cfgs) {
- result[i] = cfg.getName();
- i++;
- }
+ private static Dictionary<String, String> createProps(String serviceName) {
+ Hashtable<String, String> result = new Hashtable<>();
+ result.put(SERVICE_NAME_OSGI_PROP, serviceName);
return result;
}
- private void checkInstanceImplementing(AutoCloseable instance,
- Set<Class<?>> configures) {
- Set<Class<?>> missing = new HashSet<>();
- for (Class<?> requiredIfc : configures) {
- if (requiredIfc.isInstance(instance) == false) {
- missing.add(requiredIfc);
- }
- }
- if (missing.isEmpty() == false) {
- throw new IllegalStateException(
- instance.getClass()
- + " does not implement following interfaces as announced by "
- + ServiceInterfaceAnnotation.class.getName()
- + " annotation :" + missing);
- }
- }
-
- private static Dictionary<String, ?> getPropertiesForOsgi(
- ModuleIdentifier moduleIdentifier) {
- Hashtable<String, String> table = new Hashtable<>();
- table.put(IMPLEMENTATION_NAME_OSGI_PROP,
- moduleIdentifier.getFactoryName());
- table.put(INSTANCE_NAME_OSGI_PROP, moduleIdentifier.getInstanceName());
- return table;
- }
public static class OsgiRegistration implements AutoCloseable {
- private final ServiceRegistration<?> serviceRegistration;
+ private static final Logger logger = LoggerFactory.getLogger(OsgiRegistration.class);
- public OsgiRegistration(ServiceRegistration<?> serviceRegistration) {
- this.serviceRegistration = serviceRegistration;
+ @GuardedBy("this")
+ private AutoCloseable instance;
+ private final ModuleIdentifier moduleIdentifier;
+ @GuardedBy("this")
+ private final Set<ServiceRegistration<?>> serviceRegistrations;
+ @GuardedBy("this")
+ private final Map<String, ServiceInterfaceAnnotation> serviceNamesToAnnotations;
+
+ public OsgiRegistration(AutoCloseable instance, ModuleIdentifier moduleIdentifier,
+ BundleContext bundleContext,
+ Map<String, ServiceInterfaceAnnotation> serviceNamesToAnnotations) {
+ this.instance = instance;
+ this.moduleIdentifier = moduleIdentifier;
+ this.serviceNamesToAnnotations = serviceNamesToAnnotations;
+ this.serviceRegistrations = registerToSR(instance, bundleContext, serviceNamesToAnnotations);
}
- public OsgiRegistration() {
- this.serviceRegistration = null;
+ private static Set<ServiceRegistration<?>> registerToSR(AutoCloseable instance, BundleContext bundleContext,
+ Map<String, ServiceInterfaceAnnotation> serviceNamesToAnnotations) {
+ Set<ServiceRegistration<?>> serviceRegistrations = new HashSet<>();
+ for (Entry<String, ServiceInterfaceAnnotation> entry : serviceNamesToAnnotations.entrySet()) {
+ Class<?> requiredInterface = entry.getValue().osgiRegistrationType();
+ checkState(requiredInterface.isInstance(instance), instance.getClass().getName() +
+ " instance should implement " + requiredInterface.getName());
+ Dictionary<String, String> propertiesForOsgi = createProps(entry.getKey());
+ ServiceRegistration<?> serviceRegistration = bundleContext
+ .registerService(requiredInterface.getName(), instance, propertiesForOsgi);
+ serviceRegistrations.add(serviceRegistration);
+ }
+ return serviceRegistrations;
}
@Override
- public void close() {
- if (serviceRegistration != null) {
- serviceRegistration.unregister();
+ public synchronized void close() {
+ for (ServiceRegistration<?> serviceRegistration : serviceRegistrations) {
+ try {
+ serviceRegistration.unregister();
+ } catch(IllegalStateException e) {
+ logger.trace("Cannot unregister {}", serviceRegistration, e);
+ }
}
+ serviceRegistrations.clear();
}
- }
+ public synchronized void updateRegistrations(Map<String, ServiceInterfaceAnnotation> newAnnotationMapping,
+ BundleContext bundleContext, AutoCloseable newInstance) {
+ boolean notEquals = this.instance != newInstance;
+ notEquals |= newAnnotationMapping.equals(serviceNamesToAnnotations) == false;
+ if (notEquals) {
+ // FIXME: changing from old state to new state can be improved by computing the diff
+ logger.debug("Detected change in service registrations for {}: old: {}, new: {}", moduleIdentifier,
+ serviceNamesToAnnotations, newAnnotationMapping);
+ close();
+ this.instance = newInstance;
+ Set<ServiceRegistration<?>> newRegs = registerToSR(instance, bundleContext, newAnnotationMapping);
+ serviceRegistrations.clear();
+ serviceRegistrations.addAll(newRegs);
+ }
+ }
+ }
}
return result;
}
+ public static Set<String> getQNames(Set<ServiceInterfaceAnnotation> siAnnotations) {
+ Set<String> qNames = new HashSet<>();
+ for (ServiceInterfaceAnnotation sia: siAnnotations) {
+ qNames.add(sia.value());
+ }
+ return Collections.unmodifiableSet(qNames);
+ }
public static Set<ServiceInterfaceAnnotation> getServiceInterfaceAnnotations(ModuleFactory factory) {
Set<Class<? extends AbstractServiceInterface>> implementedServiceIntefaces = Collections.unmodifiableSet(factory.getImplementedServiceIntefaces());
result.add(annotation);
}
}
- return result;
+ return Collections.unmodifiableSet(result);
}
static Set<Class<? extends AbstractServiceInterface>> getAllAbstractServiceInterfaceClasses(
*/
package org.opendaylight.controller.config.manager;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verifyZeroInteractions;
-
-import java.lang.management.ManagementFactory;
-
import org.junit.Test;
import org.opendaylight.controller.config.manager.impl.AbstractLockedPlatformMBeanServerTest;
import org.opendaylight.controller.config.manager.impl.ConfigRegistryImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.lang.management.ManagementFactory;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
public class ConfigRegistryImplTest extends
AbstractLockedPlatformMBeanServerTest {
private static final Logger logger = LoggerFactory
BundleContext context = mock(BundleContext.class);
ConfigRegistryImpl configRegistry = null;
try {
- ModuleFactoriesResolver resolver = new HardcodedModuleFactoriesResolver(
+ ModuleFactoriesResolver resolver = new HardcodedModuleFactoriesResolver(mock(BundleContext.class),
factory, factory);
configRegistry = new ConfigRegistryImpl(resolver,
package org.opendaylight.controller.config.manager.impl;
import com.google.common.base.Preconditions;
-import junit.framework.Assert;
import org.junit.After;
+import org.junit.Before;
import org.mockito.Matchers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.opendaylight.controller.config.api.jmx.CommitStatus;
import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import javax.management.InstanceAlreadyExistsException;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.management.RuntimeMBeanException;
-import java.io.Closeable;
-import java.io.InputStream;
import java.lang.management.ManagementFactory;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Dictionary;
+import java.util.LinkedList;
import java.util.List;
import java.util.Set;
protected ConfigRegistryJMXClient configRegistryClient;
protected BaseJMXRegistrator baseJmxRegistrator;
protected InternalJMXRegistrator internalJmxRegistrator;
- protected BundleContext mockedContext = mock(BundleContext.class);
+ @Mock
+ protected BundleContext mockedContext;
+ @Mock
protected ServiceRegistration<?> mockedServiceRegistration;
- private static final Logger logger = LoggerFactory.getLogger(AbstractConfigTest.class);
+ @Before
+ public void setUpMocks() {
+ MockitoAnnotations.initMocks(this);
+ }
+
// Default handler for OSGi service registration
- private static final BundleContextServiceRegistrationHandler noopServiceRegHandler = new BundleContextServiceRegistrationHandler() {
+ protected static class RecordingBundleContextServiceRegistrationHandler implements BundleContextServiceRegistrationHandler {
+ private final List<RegistrationHolder> registrations = new LinkedList<>();
@Override
- public void handleServiceRegistration(Object serviceInstance) {}
- };
+ public void handleServiceRegistration(Class<?> clazz, Object serviceInstance, Dictionary<String, ?> props) {
+
+ registrations.add(new RegistrationHolder(clazz, serviceInstance, props));
+ }
+
+ public List<RegistrationHolder> getRegistrations() {
+ return registrations;
+ }
+
+ protected static class RegistrationHolder {
+ protected final Class<?> clazz;
+ protected final Object instance;
+ protected final Dictionary<String, ?> props;
+
+ public RegistrationHolder(Class<?> clazz, Object instance, Dictionary<String, ?> props) {
+ this.clazz = clazz;
+ this.instance = instance;
+ this.props = props;
+ }
+ }
+
+ }
+
+ protected BundleContextServiceRegistrationHandler currentBundleContextServiceRegistrationHandler;
protected BundleContextServiceRegistrationHandler getBundleContextServiceRegistrationHandler(Class<?> serviceType) {
- return noopServiceRegHandler;
+ return currentBundleContextServiceRegistrationHandler;
}
// this method should be called in @Before
protected void initConfigTransactionManagerImpl(
ModuleFactoriesResolver resolver) {
+
final MBeanServer platformMBeanServer = ManagementFactory
.getPlatformMBeanServer();
- configRegistryJMXRegistrator = new ConfigRegistryJMXRegistrator(
- platformMBeanServer);
+ configRegistryJMXRegistrator = new ConfigRegistryJMXRegistrator(platformMBeanServer);
initBundleContext();
internalJmxRegistrator = new InternalJMXRegistrator(platformMBeanServer);
throw new RuntimeException(e);
}
configRegistryClient = new ConfigRegistryJMXClient(platformMBeanServer);
+ currentBundleContextServiceRegistrationHandler = new RecordingBundleContextServiceRegistrationHandler();
}
private void initBundleContext() {
- this.mockedServiceRegistration = mock(ServiceRegistration.class);
doNothing().when(mockedServiceRegistration).unregister();
-
RegisterServiceAnswer answer = new RegisterServiceAnswer();
-
- doAnswer(answer).when(mockedContext).registerService(Matchers.any(String[].class),
- any(Closeable.class), Matchers.<Dictionary<String, ?>>any());
- doAnswer(answer).when(mockedContext).registerService(Matchers.<Class<Closeable>>any(), any(Closeable.class),
- Matchers.<Dictionary<String, ?>>any());
- }
-
-
- public Collection<InputStream> getFilesAsInputStreams(List<String> paths) {
- final Collection<InputStream> resources = new ArrayList<>();
- List<String> failedToFind = new ArrayList<>();
- for (String path : paths) {
- InputStream resourceAsStream = getClass().getResourceAsStream(path);
- if (resourceAsStream == null) {
- failedToFind.add(path);
- } else {
- resources.add(resourceAsStream);
- }
- }
- Assert.assertEquals("Some files were not found", Collections.<String>emptyList(), failedToFind);
-
- return resources;
+ doAnswer(answer).when(mockedContext).registerService(Matchers.<String>any(), any(), Matchers.<Dictionary<String, ?>>any());
+ doAnswer(answer).when(mockedContext).registerService(Matchers.<Class>any(), any(), Matchers.<Dictionary<String, ?>>any());
}
@After
transaction.commit();
}
- protected void assertSame(ObjectName oN1, ObjectName oN2) {
- assertEquals(oN1.getKeyProperty("instanceName"),
- oN2.getKeyProperty("instanceName"));
- assertEquals(oN1.getKeyProperty("interfaceName"),
- oN2.getKeyProperty("interfaceName"));
- }
-
protected void assertStatus(CommitStatus status, int expectedNewInstances,
int expectedRecreatedInstances, int expectedReusedInstances) {
assertEquals("New instances mismatch in " + status, expectedNewInstances, status.getNewInstances().size());
.size());
}
- protected ObjectName createTestConfigBean(
- ConfigTransactionJMXClient transaction, String implementationName,
- String name) throws InstanceAlreadyExistsException {
- return transaction.createModule(implementationName,
- name);
- }
protected void assertBeanCount(int i, String configMXBeanName) {
assertEquals(i, configRegistry.lookupConfigBeans(configMXBeanName)
.size());
}
- protected void assertBeanExists(int count, String moduleName,
- String instanceName) {
- assertEquals(1,
- configRegistry.lookupConfigBeans(moduleName, instanceName)
- .size());
- }
-
/**
*
* @param configBeanClass
public static interface BundleContextServiceRegistrationHandler {
- void handleServiceRegistration(Object serviceInstance);
+ void handleServiceRegistration(Class<?> clazz, Object serviceInstance, Dictionary<String, ?> props);
}
Object serviceTypeRaw = args[0];
Object serviceInstance = args[1];
+ Dictionary<String, ?> props = (Dictionary) args[2];
if (serviceTypeRaw instanceof Class) {
Class<?> serviceType = (Class<?>) serviceTypeRaw;
- invokeServiceHandler(serviceInstance, serviceType);
+ invokeServiceHandler(serviceInstance, serviceType, props);
} else if(serviceTypeRaw instanceof String[]) {
for (String className : (String[]) serviceTypeRaw) {
- try {
- Class<?> serviceType = Class.forName(className);
- invokeServiceHandler(serviceInstance, serviceType);
- } catch (ClassNotFoundException e) {
- logger.warn("Not handling service registration of type {} ", className, e);
- }
+ invokeServiceHandler(serviceInstance, className, props);
}
+ } else if (serviceTypeRaw instanceof String) {
+ invokeServiceHandler(serviceInstance, (String) serviceTypeRaw, props);
+ } else {
+ throw new IllegalStateException("Not handling service registration of type, Unknown type" + serviceTypeRaw);
+ }
- } else
- logger.debug("Not handling service registration of type {}, Unknown type", serviceTypeRaw);
return mockedServiceRegistration;
}
- private void invokeServiceHandler(Object serviceInstance, Class<?> serviceType) {
+ public void invokeServiceHandler(Object serviceInstance, String className, Dictionary<String, ?> props) {
+ try {
+ Class<?> serviceType = Class.forName(className);
+ invokeServiceHandler(serviceInstance, serviceType, props);
+ } catch (ClassNotFoundException e) {
+ throw new IllegalStateException("Not handling service registration of type " + className, e);
+ }
+ }
+
+ private void invokeServiceHandler(Object serviceInstance, Class<?> serviceType, Dictionary<String, ?> props) {
BundleContextServiceRegistrationHandler serviceRegistrationHandler = getBundleContextServiceRegistrationHandler(serviceType);
if (serviceRegistrationHandler != null) {
- serviceRegistrationHandler.handleServiceRegistration(serviceType.cast(serviceInstance));
+ serviceRegistrationHandler.handleServiceRegistration(serviceType, serviceInstance, props);
}
}
}
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import org.opendaylight.controller.config.api.ServiceReferenceWritableRegistry;
import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
import org.opendaylight.controller.config.manager.impl.jmx.BaseJMXRegistrator;
import org.opendaylight.controller.config.manager.impl.jmx.TransactionJMXRegistrator;
}
}, currentlyRegisteredFactories);
- ServiceReferenceWritableRegistry writableRegistry = ServiceReferenceRegistryImpl.createSRWritableRegistry(
+ SearchableServiceReferenceWritableRegistry writableRegistry = ServiceReferenceRegistryImpl.createSRWritableRegistry(
ServiceReferenceRegistryImpl.createInitialSRLookupRegistry(), txLookupRegistry, currentlyRegisteredFactories);
@Before
public void setUp() {
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver());
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext));
}
import org.junit.Before;
import org.junit.Test;
import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
+import org.opendaylight.controller.config.manager.impl.AbstractConfigTest.RecordingBundleContextServiceRegistrationHandler.RegistrationHolder;
import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
import org.opendaylight.controller.config.manager.impl.jmx.ServiceReferenceMXBean;
import org.opendaylight.controller.config.manager.testingservices.parallelapsp.TestingParallelAPSPModuleFactory;
import org.opendaylight.controller.config.manager.testingservices.scheduledthreadpool.TestingScheduledThreadPoolModuleFactory;
import org.opendaylight.controller.config.manager.testingservices.seviceinterface.TestingThreadPoolServiceInterface;
import org.opendaylight.controller.config.manager.testingservices.threadpool.TestingFixedThreadPoolModuleFactory;
+import org.opendaylight.controller.config.manager.testingservices.threadpool.TestingThreadPoolIfc;
import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
import javax.management.Attribute;
import javax.management.MBeanException;
import javax.management.ObjectName;
import javax.management.ReflectionException;
-
+import java.util.List;
import java.util.Map;
import java.util.Set;
@Before
public void setUp() {
super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(
+ mockedContext,
new TestingFixedThreadPoolModuleFactory(),
new TestingParallelAPSPModuleFactory(),
new TestingScheduledThreadPoolModuleFactory()));
// create apsp-parallel
createParallelAPSP(transaction1, serviceReference);
transaction1.commit();
+
// check fixed1 is used
ServiceReferenceMXBean serviceReferenceMXBean = JMX.newMXBeanProxy(platformMBeanServer,
withoutTransactionName(serviceReference), ServiceReferenceMXBean.class);
assertEquals(withoutTransactionName(fixedTPTransactionON), serviceReferenceMXBean.getCurrentImplementation());
checkApspThreadCount(fixedNrOfThreads);
+ // check OSGi SR
+ List<RegistrationHolder> registrations =
+ ((RecordingBundleContextServiceRegistrationHandler) currentBundleContextServiceRegistrationHandler).getRegistrations();
+ assertEquals(1, registrations.size());
+ RegistrationHolder record = registrations.get(0);
+ assertEquals(TestingThreadPoolIfc.class, record.clazz);
+ assertEquals(ImmutableMap.of("name","ref"), (Map<String, String>) record.props);
// switch reference to scheduled
ConfigTransactionJMXClient transaction2 = configRegistryClient.createTransaction();
*/
package org.opendaylight.controller.config.manager.impl.dependencyresolver;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
+
+import java.util.Arrays;
+import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.opendaylight.controller.config.api.JmxAttribute;
import org.opendaylight.controller.config.manager.impl.jmx.TransactionModuleJMXRegistrator.TransactionModuleJMXRegistration;
import org.opendaylight.controller.config.spi.Module;
import org.opendaylight.controller.config.spi.ModuleFactory;
-
-import java.util.Arrays;
-import java.util.List;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.reset;
+import org.osgi.framework.BundleContext;
public class DependencyResolverManagerTest {
moduleFactory,
maybeOldInternalInfo,
transactionModuleJMXRegistration,
- isDefaultBean);
+ isDefaultBean, mock(BundleContext.class));
}
private static Module mockedModule() {
}
}
- public HardcodedModuleFactoriesResolver(ModuleFactory... list) {
- this(mockBundleContext(),list);
- }
-
private static BundleContext mockBundleContext() {
BundleContext bundleContext = Mockito.mock(BundleContext.class);
ServiceRegistration<ModuleFactory> serviceRegistration = mock(ServiceRegistration.class);
@Before
public void setUp() {
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,
new TestingFixedThreadPoolModuleFactory(),
new TestingParallelAPSPModuleFactory()));
}
*/
package org.opendaylight.controller.config.manager.testingservices.parallelapsp.test;
-import java.io.Closeable;
-import java.io.IOException;
-import java.util.concurrent.Executor;
-
-import javax.management.ObjectName;
-
import org.junit.Before;
import org.junit.Test;
import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
import org.opendaylight.controller.config.spi.Module;
import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
+import javax.management.ObjectName;
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.concurrent.Executor;
+
public class MockedDependenciesTest extends AbstractParallelAPSPTest {
private final String threadPoolImplementationName = "mockedthreadpool";
ClassBasedModuleFactory mockedThreadPoolConfigFactory = new ClassBasedModuleFactory(
threadPoolImplementationName, MockedThreadPoolModule.class);
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,
new TestingParallelAPSPModuleFactory(),
mockedThreadPoolConfigFactory));
}
*/
package org.opendaylight.controller.config.manager.testingservices.scheduledthreadpool.test;
-import static org.junit.Assert.assertEquals;
-
import org.junit.After;
import org.junit.Before;
import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
import org.opendaylight.controller.config.manager.testingservices.parallelapsp.TestingParallelAPSPModuleFactory;
import org.opendaylight.controller.config.manager.testingservices.scheduledthreadpool.TestingScheduledThreadPoolImpl;
-import org.opendaylight.controller.config.manager.testingservices.scheduledthreadpool
- .TestingScheduledThreadPoolModuleFactory;
+import org.opendaylight.controller.config.manager.testingservices.scheduledthreadpool.TestingScheduledThreadPoolModuleFactory;
import org.opendaylight.controller.config.manager.testingservices.threadpool.TestingFixedThreadPoolModuleFactory;
+import static org.junit.Assert.assertEquals;
+
public abstract class AbstractScheduledTest extends AbstractConfigTest {
protected static final String scheduled1 = "scheduled1";
public final void setUp() {
assertEquals(0,
TestingScheduledThreadPoolImpl.getNumberOfCloseMethodCalls());
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,
new TestingScheduledThreadPoolModuleFactory(),
new TestingFixedThreadPoolModuleFactory(),
new TestingParallelAPSPModuleFactory()));
@Override
public void close() throws IOException {
executorService.shutdown();
+ allExecutors.remove(executorService);
}
--- /dev/null
+/*
+ * Copyright (c) 2014 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,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.config.manager.testingservices.threadpool.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.doReturn;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Map.Entry;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
+import org.opendaylight.controller.config.manager.impl.factoriesresolver.ModuleFactoriesResolver;
+import org.opendaylight.controller.config.manager.testingservices.threadpool.TestingFixedThreadPool;
+import org.opendaylight.controller.config.manager.testingservices.threadpool.TestingFixedThreadPoolModuleFactory;
+import org.opendaylight.controller.config.spi.ModuleFactory;
+import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
+import org.osgi.framework.BundleContext;
+
+public class ShutdownTest extends AbstractConfigTest {
+ private final TestingFixedThreadPoolModuleFactory testingFixedThreadPoolModuleFactory = new TestingFixedThreadPoolModuleFactory();
+
+ @Mock
+ ModuleFactoriesResolver mockedResolver;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ Map<String, Entry<ModuleFactory, BundleContext>> allFactories = ImmutableMap.of(
+ testingFixedThreadPoolModuleFactory.getImplementationName(),
+ Maps.<ModuleFactory, BundleContext>immutableEntry(testingFixedThreadPoolModuleFactory, mockedContext));
+ doReturn(allFactories).when(mockedResolver).getAllFactories();
+ super.initConfigTransactionManagerImpl(mockedResolver);
+ }
+
+
+ @Test
+ public void testCreateAndDestroyBeanInSameTransaction() throws Exception {
+ {
+ ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
+ SimpleConfigurationTest.createFixedThreadPool(transaction);
+ transaction.commit();
+ }
+ assertEquals(1, TestingFixedThreadPool.allExecutors.size());
+ doReturn(Collections.emptyMap()).when(mockedResolver).getAllFactories();
+ {
+ ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
+ transaction.commit();
+ }
+ assertEquals(1, TestingFixedThreadPool.allExecutors.size());
+ }
+}
* dependencies.
*/
public class SimpleConfigurationTest extends AbstractConfigTest {
- private final int numberOfThreads = 5;
+ private static final int numberOfThreads = 5;
private final int numberOfThreads2 = 10;
private static final String fixed1 = "fixed1";
private static final List<ObjectName> emptyONs = Collections
@Before
public void setUp() {
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,
new TestingFixedThreadPoolModuleFactory()));
}
return fixed1names;
}
- private ObjectName createFixedThreadPool(
+ static ObjectName createFixedThreadPool(
ConfigTransactionJMXClient transaction)
throws InstanceAlreadyExistsException, InstanceNotFoundException {
transaction.assertVersion(0, 1);
// 4, check
assertEquals(2, configRegistryClient.getVersion());
- assertEquals(1, TestingFixedThreadPool.allExecutors.size());
- assertTrue(TestingFixedThreadPool.allExecutors.get(0).isShutdown());
+ assertEquals(0, TestingFixedThreadPool.allExecutors.size());
// dynamic config should be removed from platform
try {
// commit
transaction.commit();
// check that first threadpool is closed
- checkThreadPools(2, numberOfThreads2);
+ checkThreadPools(1, numberOfThreads2);
}
private void checkThreadPools(int expectedTotalNumberOfExecutors,
// commit
CommitStatus commitStatus = transaction.commit();
// check that new threadpool is created and old one is closed
- checkThreadPools(2, numberOfThreads);
+ checkThreadPools(1, numberOfThreads);
CommitStatus expected = new CommitStatus(emptyONs, emptyONs, fixed1List);
assertEquals(expected, commitStatus);
}
platformMBeanServer.getMBeanInfo(transaction.getObjectName());
fail();
}catch(InstanceNotFoundException e){
+ assertEquals("org.opendaylight.controller:TransactionName=ConfigTransaction-0-1,type=ConfigTransaction", e.getMessage());
}
}
public void setUp() throws Exception {
factory = new LogbackModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory));
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory));
}
@Test
public void setUp() throws IOException, ClassNotFoundException {
factory = new LogbackModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory));
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory));
}
/**
public void setUp() throws JoranException, IOException {
factory = new LogbackModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory));
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory));
lc = (LoggerContext) LoggerFactory.getILoggerFactory();
JoranConfigurator configurator = new JoranConfigurator();
@Before
public void setUp() {
factory = new GlobalEventExecutorModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory));
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory));
}
@Test
@Before
public void setUp() {
factory = new NettyThreadgroupModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory));
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory));
}
@Test
class StopSystemBundleThread extends Thread {
private static final Logger logger = LoggerFactory.getLogger(StopSystemBundleThread.class);
- public static final String CONFIG_MANAGER_SYMBOLIC_NAME = "org.opendaylight.controller.config-manager";
private final Bundle systemBundle;
StopSystemBundleThread(Bundle systemBundle) {
try {
// wait so that JMX response is received
Thread.sleep(1000);
- // first try to stop config-manager
- Bundle configManager = findConfigManager();
- if (configManager != null){
- logger.debug("Stopping config-manager");
- configManager.stop();
- Thread.sleep(1000);
- }
logger.debug("Stopping system bundle");
systemBundle.stop();
} catch (BundleException e) {
logger.warn("Shutdown process interrupted", e);
}
}
-
- private Bundle findConfigManager() {
- for(Bundle bundle: systemBundle.getBundleContext().getBundles()){
- if (CONFIG_MANAGER_SYMBOLIC_NAME.equals(bundle.getSymbolicName())) {
- return bundle;
- }
- }
- return null;
- }
-
}
class CallSystemExitThread extends Thread {
*/
package org.opendaylight.controller.config.yang.shutdown.impl;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.verify;
+import static org.opendaylight.controller.config.yang.shutdown.impl.ShutdownModuleFactory.NAME;
+
+import java.util.Collections;
+import javax.management.InstanceNotFoundException;
+import javax.management.JMX;
+import javax.management.ObjectName;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
import org.osgi.framework.Bundle;
-import javax.management.InstanceNotFoundException;
-import javax.management.JMX;
-import javax.management.ObjectName;
-import java.util.Collections;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.verify;
-import static org.opendaylight.controller.config.yang.shutdown.impl.ShutdownModuleFactory.NAME;
-
public class ShutdownTest extends AbstractConfigTest {
private final ShutdownModuleFactory factory = new ShutdownModuleFactory();
@Mock
- private Bundle mockedSysBundle, mockedConfigManager;
+ private Bundle mockedSysBundle;
@Before
doReturn(mockedSysBundle).when(mockedContext).getBundle(0);
mockedContext.getBundle(0);
doNothing().when(mockedSysBundle).stop();
- doNothing().when(mockedConfigManager).stop();
doReturn(mockedContext).when(mockedSysBundle).getBundleContext();
- doReturn(new Bundle[]{mockedSysBundle, mockedConfigManager}).when(mockedContext).getBundles();
+ doReturn(new Bundle[]{mockedSysBundle}).when(mockedContext).getBundles();
doReturn("system bundle").when(mockedSysBundle).getSymbolicName();
- doReturn(StopSystemBundleThread.CONFIG_MANAGER_SYMBOLIC_NAME).when(mockedConfigManager).getSymbolicName();
+
ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
private void assertStopped() throws Exception {
Thread.sleep(3000); // happens on another thread
- verify(mockedConfigManager).stop();
verify(mockedSysBundle).stop();
}
}
TestingScheduledThreadPoolModule.class, poolImplName);
factory = new AsyncEventBusModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory,
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory,
scheduledThreadPoolConfigFactory));
}
*/
package org.opendaylight.controller.config.threadpool.eventbus;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.fail;
-import static org.junit.matchers.JUnitMatchers.containsString;
-
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.ObjectName;
-
import org.junit.Before;
import org.junit.Test;
import org.opendaylight.controller.config.api.ConflictingVersionException;
import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
import org.opendaylight.controller.config.yang.threadpool.impl.EventBusModuleFactory;
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.ObjectName;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+import static org.junit.matchers.JUnitMatchers.containsString;
+
public class SyncEventBusConfigBeanTest extends AbstractConfigTest {
private EventBusModuleFactory factory;
public void setUp() {
factory = new EventBusModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory));
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory));
}
@Test
@Before
public void setUp() {
factory = new FixedThreadPoolModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory,
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory,
new NamingThreadFactoryModuleFactory()));
}
public void setUp() {
flexibleFactory = new FlexibleThreadPoolModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(flexibleFactory,
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,flexibleFactory,
new NamingThreadFactoryModuleFactory()));
}
import javax.management.InstanceAlreadyExistsException;
import javax.management.InstanceNotFoundException;
import javax.management.ObjectName;
-
import org.junit.Before;
import org.junit.Test;
import org.opendaylight.controller.config.api.ConflictingVersionException;
public void setUp() {
factory = new NamingThreadFactoryModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory));
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, factory));
}
@Test
public void setUp() {
factory = new ScheduledThreadPoolModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory,
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, factory,
new NamingThreadFactoryModuleFactory()));
}
*/
package org.opendaylight.controller.config.yangjmxgenerator.it;
-import static org.junit.Assert.fail;
-
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.ObjectName;
-
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.opendaylight.controller.config.yang.test.impl.TestImplModuleFactory;
import org.opendaylight.controller.config.yang.test.impl.TestImplModuleMXBean;
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.ObjectName;
+
+import static org.junit.Assert.fail;
+
@Ignore
// ietf beans are not JMX compliant beans:
// Do not know how to make a
public void setUp() {
factory = new TestImplModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,
factory));
}
public void setUp() {
factory = new NetconfTestImplModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory,
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory,
new DepTestImplModuleFactory(), new IdentityTestModuleFactory()));
}
</provider>
</instance>
</service>
+
<service>
<type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">
binding:binding-broker-osgi-registry
</provider>
</instance>
</service>
+ <service>
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-rpc-registry</type>
+ <instance>
+ <name>binding-rpc-broker</name>
+ <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
+ </instance>
+ </service>
<service>
<type xmlns:binding-impl="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
binding-impl:binding-dom-mapping-service
this.factory = new NetconfTestImplModuleFactory();
this.factory2 = new DepTestImplModuleFactory();
this.factory3 = new IdentityTestModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(this.factory, this.factory2,
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, this.factory, this.factory2,
this.factory3));
transactionProvider = new TransactionProvider(this.configRegistryClient, NETCONF_SESSION_ID);
long maxWaitForCapabilitiesMillis = getMaxWaitForCapabilitiesMillis(propertiesProvider);
List<ConfigSnapshotHolder> configs = persisterAggregator.loadLastConfigs();
long conflictingVersionTimeoutMillis = getConflictingVersionTimeoutMillis(propertiesProvider);
- logger.trace("Following configs will be pushed: {}", configs);
+ logger.debug("Following configs will be pushed: {}", configs);
InnerCustomizer innerCustomizer = new InnerCustomizer(configs, maxWaitForCapabilitiesMillis,
conflictingVersionTimeoutMillis, persisterAggregator);
public DefaultCommitNotificationProducer(MBeanServer mBeanServer) {
this.mbeanServer = mBeanServer;
+ logger.debug("Registering to JMX under {}", on);
registerMBean(this, mbeanServer, on);
}
@Before
public void setUp() throws Exception {
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(NetconfITTest.getModuleFactoriesS().toArray(
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,NetconfITTest.getModuleFactoriesS().toArray(
new ModuleFactory[0])));
NetconfMonitoringServiceImpl monitoringService = new NetconfMonitoringServiceImpl(getNetconfOperationProvider());
@Before
public void setUp() throws Exception {
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(getModuleFactories().toArray(
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,getModuleFactories().toArray(
new ModuleFactory[0])));
NetconfOperationServiceFactoryListenerImpl factoriesListener = new NetconfOperationServiceFactoryListenerImpl();
@Before
public void setUp() throws Exception {
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(getModuleFactories().toArray(
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,getModuleFactories().toArray(
new ModuleFactory[0])));
loadMessages();
@Before
public void setUp() throws Exception {
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(NetconfITTest.getModuleFactoriesS().toArray(
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, NetconfITTest.getModuleFactoriesS().toArray(
new ModuleFactory[0])));
monitoringService = new NetconfMonitoringServiceImpl(getNetconfOperationProvider());