Create dummy MBean - ServiceReferenceMXBean - that contains link to implementation of the service as an attribute.
Add support for resolving of SR to dependency resolver. Each time user saves SR, create MBean and
add the interface QName together with user defined reference name to ObjectName of the newly created SR MBean.
Change-Id: I71ddb762e00d9be8b426fb979ff5ade046d46050
Signed-off-by: Tomas Olvecky <tolvecky@cisco.com>
/**
* Represents functionality provided by configuration transaction.
*/
-public interface ConfigTransactionController extends LookupRegistry, ServiceReferenceReadableRegistry, ServiceReferenceWritableRegistry {
+public interface ConfigTransactionController extends LookupRegistry, ServiceReferenceWritableRegistry {
/**
* Create new configuration bean.
*/
void checkConfigBeanExists(ObjectName objectName) throws InstanceNotFoundException;
+
/**
- * @return qnames of all ModuleFactory instances in the system
+ * @return qNames of all ModuleFactory instances in the system
*/
Set<String> getAvailableModuleFactoryQNames();
/**
* Lookup object name by fully qualified service interface name and service reference name.
- * @param serviceInterfaceName service interface name
+ * @param serviceInterfaceQName service interface name
* @param refName service reference name supplied in
* {@link org.opendaylight.controller.config.api.ConfigTransactionController#saveServiceReference(String, String, javax.management.ObjectName)}
* @throws java.lang.IllegalArgumentException if module not found
*/
- ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceName, String refName);
+ ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceQName, String refName);
/**
* Get mapping of services to reference names and module object names.
*/
- Map<String /* serviceInterfaceName */, Map<String/* refName */, ObjectName>> getServiceMapping();
+ Map<String /* serviceInterfaceQName */, Map<String/* refName */, ObjectName>> getServiceMapping();
/**
* Get current mapping between reference names and module object names for given service interface name.
- * @param serviceInterfaceName service interface name
+ * @param serviceInterfaceQName service interface name
* @throws IllegalArgumentException if there is a mismatch between serviceInterfaceName and objectName
*/
- Map<String /* refName */, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName);
+ Map<String /* refName */, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceQName);
/**
* Find all available service interface names of a module.
*/
String getServiceInterfaceName(String namespace, String localName);
+ /**
+ * @return ObjectName with type=Service that was created using
+ * {@link org.opendaylight.controller.config.api.ServiceReferenceWritableRegistry#saveServiceReference(String, String,
+ * javax.management.ObjectName)}
+ */
+ ObjectName getServiceReference(String serviceInterfaceQName, String refName) throws InstanceNotFoundException;
+
+ void checkServiceReferenceExists(ObjectName objectName) throws InstanceNotFoundException;
+
}
public interface ServiceReferenceWritableRegistry extends ServiceReferenceReadableRegistry {
/**
* Create or update reference name to objectName. Reference name is unique per service interface name.
+ * @return created or updated object name containing service name and reference name
* @throws IllegalArgumentException if there is a mismatch between serviceInterfaceName and objectName
* @throws InstanceNotFoundException if search did not find exactly one instance
*/
- void saveServiceReference(String serviceInterfaceName, String refName, ObjectName objectName) throws InstanceNotFoundException;
+ ObjectName saveServiceReference(String serviceInterfaceName, String refName, ObjectName moduleON) throws InstanceNotFoundException;
/**
* Remove service reference.
* @return true iif removed
* @throws IllegalArgumentException if service interface name is not advertised by any module
*/
- boolean removeServiceReference(String serviceInterfaceName, String refName);
+ void removeServiceReference(String serviceInterfaceName, String refName) throws InstanceNotFoundException;
/**
* Remove all service references.
* is defined as {@link #ON_DOMAIN} and at least one key-value pair. The only
* mandatory property is {@link #TYPE_KEY}. All transaction related mbeans have
* {@link #TRANSACTION_NAME_KEY} property set.
- *
*/
@ThreadSafe
public class ObjectNameUtil {
public static final String ON_DOMAIN = ConfigRegistryConstants.ON_DOMAIN;
public static final String MODULE_FACTORY_NAME_KEY = "moduleFactoryName";
+ public static final String SERVICE_QNAME_KEY = "serviceQName";
public static final String INSTANCE_NAME_KEY = "instanceName";
public static final String TYPE_KEY = ConfigRegistryConstants.TYPE_KEY;
public static final String TYPE_CONFIG_REGISTRY = ConfigRegistryConstants.TYPE_CONFIG_REGISTRY;
public static final String TYPE_CONFIG_TRANSACTION = "ConfigTransaction";
public static final String TYPE_MODULE = "Module";
+ public static final String TYPE_SERVICE_REFERENCE = "ServiceReference";
public static final String TYPE_RUNTIME_BEAN = "RuntimeBean";
-
public static final String TRANSACTION_NAME_KEY = "TransactionName";
+ public static final String REF_NAME_KEY = "RefName";
+ private static final String REPLACED_QUOTATION_MARK = "\\?";
public static ObjectName createON(String on) {
try {
return ConfigRegistryConstants.createON(name, key, value);
}
- public static ObjectName createON(String name, Map<String, String> attribs) {
+ public static ObjectName createON(String domain, Map<String, String> attribs) {
Hashtable<String, String> table = new Hashtable<>(attribs);
try {
- return new ObjectName(name, table);
+ return new ObjectName(domain, table);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static ObjectName createTransactionModuleON(String transactionName,
- ModuleIdentifier moduleIdentifier) {
+ ModuleIdentifier moduleIdentifier) {
return createTransactionModuleON(transactionName,
moduleIdentifier.getFactoryName(),
moduleIdentifier.getInstanceName());
}
public static ObjectName createTransactionModuleON(String transactionName,
- String moduleName, String instanceName) {
- Map<String, String> onParams = createModuleON(moduleName, instanceName);
+ String moduleName, String instanceName) {
+ Map<String, String> onParams = createModuleMap(moduleName, instanceName);
onParams.put(TRANSACTION_NAME_KEY, transactionName);
return createON(ON_DOMAIN, onParams);
}
public static ObjectName createTransactionModuleON(String transactionName,
- ObjectName on) {
+ ObjectName on) {
return createTransactionModuleON(transactionName, getFactoryName(on),
getInstanceName(on));
}
moduleIdentifier.getInstanceName());
}
+ public static ObjectName createReadOnlyServiceON(String serviceQName, String refName) {
+ Map<String, String> onParams = createServiceMap(serviceQName, refName);
+ return createON(ON_DOMAIN, onParams);
+ }
+
+ public static ObjectName createTransactionServiceON(String transactionName, String serviceQName, String refName) {
+ Map<String, String> onParams = createServiceON(transactionName, serviceQName, refName);
+ return createON(ON_DOMAIN, onParams);
+ }
+
+ public static String getServiceQName(ObjectName objectName) {
+ checkType(objectName, TYPE_SERVICE_REFERENCE);
+ String quoted = objectName.getKeyProperty(SERVICE_QNAME_KEY);
+ String result = unquoteAndUnescape(objectName, quoted);
+ return result;
+ }
+
+ // ObjectName supports quotation and ignores tokens like =, but fails to ignore ? sign.
+ // It must be replaced with another character that hopefully does not collide
+ // with actual value.
+ private static String unquoteAndUnescape(ObjectName objectName, String quoted) {
+ if (quoted == null) {
+ throw new IllegalArgumentException("Cannot find " + SERVICE_QNAME_KEY + " in " + objectName);
+ }
+ if (quoted.startsWith("\"") == false || quoted.endsWith("\"") == false) {
+ throw new IllegalArgumentException("Quotes not found in " + objectName);
+ }
+ String substring = quoted.substring(1);
+ substring = substring.substring(0, substring.length() - 1);
+ substring = substring.replace(REPLACED_QUOTATION_MARK, "?");
+ return substring;
+ }
+
+ private static String quoteAndEscapeValue(String serviceQName) {
+ return "\"" + serviceQName.replace("?", REPLACED_QUOTATION_MARK) + "\"";
+ }
+
+ public static String getReferenceName(ObjectName objectName) {
+ checkType(objectName, TYPE_SERVICE_REFERENCE);
+ return objectName.getKeyProperty(REF_NAME_KEY);
+ }
+
+ private static Map<String, String> createServiceON(String transactionName, String serviceQName,
+ String refName) {
+ Map<String, String> result = new HashMap<>(createServiceMap(serviceQName, refName));
+ result.put(TRANSACTION_NAME_KEY, transactionName);
+ return result;
+ }
+
+ private static Map<String, String> createServiceMap(String serviceQName,
+ String refName) {
+ Map<String, String> onParams = new HashMap<>();
+ onParams.put(TYPE_KEY, TYPE_SERVICE_REFERENCE);
+ onParams.put(SERVICE_QNAME_KEY, quoteAndEscapeValue(serviceQName));
+ onParams.put(REF_NAME_KEY, refName);
+ return onParams;
+ }
+
+
public static ObjectName createReadOnlyModuleON(String moduleName,
- String instanceName) {
- Map<String, String> onParams = createModuleON(moduleName, instanceName);
+ String instanceName) {
+ Map<String, String> onParams = createModuleMap(moduleName, instanceName);
return createON(ON_DOMAIN, onParams);
}
- private static Map<String, String> createModuleON(String moduleName,
- String instanceName) {
+ private static Map<String, String> createModuleMap(String moduleName,
+ String instanceName) {
Map<String, String> onParams = new HashMap<>();
onParams.put(TYPE_KEY, TYPE_MODULE);
onParams.put(MODULE_FACTORY_NAME_KEY, moduleName);
}
public static String getFactoryName(ObjectName objectName) {
+ checkTypeOneOf(objectName, TYPE_MODULE, TYPE_RUNTIME_BEAN);
return objectName.getKeyProperty(MODULE_FACTORY_NAME_KEY);
}
public static String getInstanceName(ObjectName objectName) {
+ checkTypeOneOf(objectName, TYPE_MODULE, TYPE_RUNTIME_BEAN);
return objectName.getKeyProperty(INSTANCE_NAME_KEY);
}
* Sanitize on: keep only mandatory attributes of module + metadata.
*/
public static ObjectName withoutTransactionName(ObjectName inputON) {
+ checkTypeOneOf(inputON, TYPE_MODULE, TYPE_SERVICE_REFERENCE);
if (getTransactionName(inputON) == null) {
throw new IllegalArgumentException(
"Expected ObjectName with transaction:" + inputON);
throw new IllegalArgumentException("Expected different domain: "
+ inputON);
}
- String moduleName = getFactoryName(inputON);
- String instanceName = getInstanceName(inputON);
-
-
+ Map<String, String> outputProperties;
+ if (inputON.getKeyProperty(TYPE_KEY).equals(TYPE_MODULE)) {
+ String moduleName = getFactoryName(inputON);
+ String instanceName = getInstanceName(inputON);
+ outputProperties = new HashMap<>(createModuleMap(moduleName, instanceName));
+ } else {
+ String serviceQName = getServiceQName(inputON);
+ String refName = getReferenceName(inputON);
+ outputProperties = new HashMap<>(createServiceMap(serviceQName, refName));
+ }
Map<String, String> allProperties = getAdditionalProperties(inputON);
- Map<String, String> outputProperties = new HashMap<>(createModuleON(moduleName, instanceName));
-
- for(Entry<String, String> entry: allProperties.entrySet()) {
+ for (Entry<String, String> entry : allProperties.entrySet()) {
if (entry.getKey().startsWith("X-")) {
outputProperties.put(entry.getKey(), entry.getValue());
}
return createON(ON_DOMAIN, outputProperties);
}
+ public static ObjectName withTransactionName(ObjectName inputON, String transactionName) {
+ Map<String, String> additionalProperties = getAdditionalProperties(inputON);
+ additionalProperties.put(TRANSACTION_NAME_KEY, transactionName);
+ return createON(inputON.getDomain(), additionalProperties);
+
+ }
+
private static void assertDoesNotContain(
Map<String, String> additionalProperties, String key) {
if (additionalProperties.containsKey(key)) {
}
public static ObjectName createRuntimeBeanName(String moduleName,
- String instanceName, Map<String, String> additionalProperties) {
+ String instanceName, Map<String, String> additionalProperties) {
// check that there is no overwriting of default attributes
assertDoesNotContain(additionalProperties, MODULE_FACTORY_NAME_KEY);
assertDoesNotContain(additionalProperties, INSTANCE_NAME_KEY);
}
}
+ public static void checkTypeOneOf(ObjectName objectName, String ... types) {
+ for(String type: types) {
+ if (type.equals(objectName.getKeyProperty(TYPE_KEY))) {
+ return;
+ }
+ }
+ throw new IllegalArgumentException("Wrong type, expected one of " + Arrays.asList(types)
+ + ", got " + objectName);
+ }
+
public static ObjectName createModulePattern(String moduleName,
- String instanceName) {
+ String instanceName) {
if (moduleName == null)
moduleName = "*";
if (instanceName == null)
}
public static ObjectName createModulePattern(String ifcName,
- String instanceName, String transactionName) {
+ String instanceName, String transactionName) {
return ObjectNameUtil.createON(ObjectNameUtil.ON_DOMAIN
+ ":type=Module," + ObjectNameUtil.MODULE_FACTORY_NAME_KEY
+ "=" + ifcName + "," + ObjectNameUtil.INSTANCE_NAME_KEY + "="
}
public static ObjectName createRuntimeBeanPattern(String moduleName,
- String instanceName) {
+ String instanceName) {
return ObjectNameUtil.createON(ObjectNameUtil.ON_DOMAIN + ":"
+ ObjectNameUtil.TYPE_KEY + "="
+ ObjectNameUtil.TYPE_RUNTIME_BEAN + ","
}
public static ModuleIdentifier fromON(ObjectName objectName,
- String expectedType) {
+ String expectedType) {
checkType(objectName, expectedType);
String factoryName = getFactoryName(objectName);
if (factoryName == null)
return new ModuleIdentifier(factoryName, instanceName);
}
+ public static boolean isServiceReference(ObjectName objectName) {
+ return TYPE_SERVICE_REFERENCE.equals(objectName.getKeyProperty(TYPE_KEY));
+ }
}
--- /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 org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
+
+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.ServiceReferenceReadableRegistry;
import org.opendaylight.controller.config.api.ServiceReferenceWritableRegistry;
import org.opendaylight.controller.config.api.ValidationException;
import org.opendaylight.controller.config.api.jmx.CommitStatus;
private List<ModuleFactory> lastListOfFactories = Collections.emptyList();
@GuardedBy("this") // switched in every 2ndPC
- private ServiceReferenceReadableRegistry readableSRRegistry = ServiceReferenceRegistryImpl.createInitialSRLookupRegistry();
+ private CloseableServiceReferenceReadableRegistry readableSRRegistry = ServiceReferenceRegistryImpl.createInitialSRLookupRegistry();
// constructor
public ConfigRegistryImpl(ModuleFactoriesResolver resolver,
OsgiRegistration osgiRegistration = null;
if (entry.hasOldModule()) {
ModuleInternalInfo oldInternalInfo = entry.getOldInternalInfo();
- DynamicReadableWrapper oldReadableConfigBean = oldInternalInfo
- .getReadableModule();
+ DynamicReadableWrapper oldReadableConfigBean = oldInternalInfo.getReadableModule();
currentConfig.remove(entry.getIdentifier());
// test if old instance == new instance
version = configTransactionController.getVersion();
// switch readable Service Reference Registry
- this.readableSRRegistry = ServiceReferenceRegistryImpl.createSRReadableRegistry(configTransactionController.getWritableRegistry(), this);
+ this.readableSRRegistry.close();
+ this.readableSRRegistry = ServiceReferenceRegistryImpl.createSRReadableRegistry(
+ configTransactionController.getWritableRegistry(), this, baseJMXRegistrator);
return new CommitStatus(newInstances, reusedInstances,
recreatedInstances);
// service reference functionality:
@Override
- public synchronized ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceName, String refName) {
- return readableSRRegistry.lookupConfigBeanByServiceInterfaceName(serviceInterfaceName, refName);
+ public synchronized ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceQName, String refName) {
+ return readableSRRegistry.lookupConfigBeanByServiceInterfaceName(serviceInterfaceQName, refName);
}
@Override
}
@Override
- public synchronized Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName) {
- return readableSRRegistry.lookupServiceReferencesByServiceInterfaceName(serviceInterfaceName);
+ public synchronized Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceQName) {
+ return readableSRRegistry.lookupServiceReferencesByServiceInterfaceName(serviceInterfaceQName);
}
@Override
return readableSRRegistry.getServiceInterfaceName(namespace, localName);
}
+ @Override
+ public void checkServiceReferenceExists(ObjectName objectName) throws InstanceNotFoundException {
+ readableSRRegistry.checkServiceReferenceExists(objectName);
+ }
+
+ @Override
+ public ObjectName getServiceReference(String serviceInterfaceQName, String refName) throws InstanceNotFoundException {
+ return readableSRRegistry.getServiceReference(serviceInterfaceQName, refName);
+ }
+
@Override
public Set<String> getAvailableModuleFactoryQNames() {
return ModuleQNameUtil.getQNames(resolver.getAllFactories());
}
+ @Override
+ public String toString() {
+ return "ConfigRegistryImpl{" +
+ "versionCounter=" + versionCounter +
+ ", version=" + version +
+ '}';
+ }
}
/**
}
private void add(ModuleInternalInfo configInfo) {
- ModuleInternalInfo oldValue = currentConfig.put(configInfo.getName(),
+ ModuleInternalInfo oldValue = currentConfig.put(configInfo.getIdentifier(),
configInfo);
if (oldValue != null) {
throw new IllegalStateException(
"Cannot overwrite module with same name:"
- + configInfo.getName() + ":" + configInfo);
+ + configInfo.getIdentifier() + ":" + configInfo);
}
}
this.currentlyRegisteredFactories = currentlyRegisteredFactories;
this.factoriesHolder = new HierarchicalConfigMBeanFactoriesHolder(currentlyRegisteredFactories);
this.transactionStatus = new TransactionStatus();
- this.dependencyResolverManager = new DependencyResolverManager(transactionName, transactionStatus);
+ this.dependencyResolverManager = new DependencyResolverManager(transactionName, transactionStatus, writableSRRegistry);
this.transactionsMBeanServer = transactionsMBeanServer;
this.configMBeanServer = configMBeanServer;
this.blankTransaction = blankTransaction;
throws InstanceAlreadyExistsException {
transactionStatus.checkNotCommitStarted();
transactionStatus.checkNotAborted();
- ModuleIdentifier moduleIdentifier = oldConfigBeanInfo.getName();
+ ModuleIdentifier moduleIdentifier = oldConfigBeanInfo.getIdentifier();
dependencyResolverManager.assertNotExists(moduleIdentifier);
ModuleFactory moduleFactory = factoriesHolder
.findByModuleName(moduleIdentifier.getFactoryName());
Module module;
- DependencyResolver dependencyResolver = dependencyResolverManager
- .getOrCreate(moduleIdentifier);
+ DependencyResolver dependencyResolver = dependencyResolverManager.getOrCreate(moduleIdentifier);
try {
BundleContext bc = getModuleFactoryBundleContext(moduleFactory.getImplementationName());
module = moduleFactory.createModule(
close();
}
- private void close() {
+ public void close() {
//FIXME: should not close object that was retrieved in constructor, a wrapper object should do that perhaps
txLookupRegistry.close();
}
@Override
- public synchronized ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceName, String refName) {
- return writableSRRegistry.lookupConfigBeanByServiceInterfaceName(serviceInterfaceName, refName);
+ public synchronized ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceQName, String refName) {
+ return writableSRRegistry.lookupConfigBeanByServiceInterfaceName(serviceInterfaceQName, refName);
}
@Override
}
@Override
- public synchronized Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName) {
- return writableSRRegistry.lookupServiceReferencesByServiceInterfaceName(serviceInterfaceName);
+ public synchronized Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceQName) {
+ return writableSRRegistry.lookupServiceReferencesByServiceInterfaceName(serviceInterfaceQName);
}
@Override
}
@Override
- public synchronized void saveServiceReference(String serviceInterfaceName, String refName, ObjectName objectName) throws InstanceNotFoundException {
- writableSRRegistry.saveServiceReference(serviceInterfaceName, refName, objectName);
+ public synchronized ObjectName saveServiceReference(String serviceInterfaceName, String refName, ObjectName moduleON) throws InstanceNotFoundException {
+ return writableSRRegistry.saveServiceReference(serviceInterfaceName, refName, moduleON);
}
@Override
- public synchronized boolean removeServiceReference(String serviceInterfaceName, String refName) {
- return writableSRRegistry.removeServiceReference(serviceInterfaceName, refName);
+ public synchronized void removeServiceReference(String serviceInterfaceName, String refName) throws InstanceNotFoundException {
+ writableSRRegistry.removeServiceReference(serviceInterfaceName, refName);
}
@Override
return txLookupRegistry.getAvailableModuleFactoryQNames();
}
+ @Override
+ public void checkServiceReferenceExists(ObjectName objectName) throws InstanceNotFoundException {
+ writableSRRegistry.checkServiceReferenceExists(objectName);
+ }
+
+ @Override
+ public ObjectName getServiceReference(String serviceInterfaceQName, String refName) throws InstanceNotFoundException {
+ return writableSRRegistry.getServiceReference(serviceInterfaceQName, refName);
+ }
}
return ModuleQNameUtil.getQNames(allCurrentFactories);
}
+
+ @Override
+ public String toString() {
+ return "ConfigTransactionLookupRegistry{" +
+ "transactionIdentifier=" + transactionIdentifier +
+ '}';
+ }
}
interface TransactionJMXRegistratorFactory {
return osgiRegistration;
}
- @Deprecated
- public ModuleIdentifier getName() {
- return name;
- }
-
/**
* Get index representing dependency ordering within a transaction.
*/
}
public DestroyedModule toDestroyedModule() {
- return new DestroyedModule(getName(),
+ return new DestroyedModule(getIdentifier(),
getReadableModule().getInstance(), getModuleJMXRegistrator(),
getOsgiRegistration(), getOrderingIdx());
}
import org.opendaylight.controller.config.api.ServiceReferenceWritableRegistry;
import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation;
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.ServiceReference;
+import org.opendaylight.controller.config.manager.impl.jmx.ServiceReferenceMXBeanImpl;
+import org.opendaylight.controller.config.manager.impl.jmx.ServiceReferenceRegistrator;
+import org.opendaylight.controller.config.manager.impl.jmx.ServiceReferenceRegistrator.ServiceReferenceJMXRegistration;
+import org.opendaylight.controller.config.manager.impl.jmx.ServiceReferenceRegistrator.ServiceReferenceTransactionRegistratorFactory;
+import org.opendaylight.controller.config.manager.impl.jmx.ServiceReferenceRegistrator.ServiceReferenceTransactionRegistratorFactoryImpl;
import org.opendaylight.controller.config.manager.impl.util.InterfacesHelper;
import org.opendaylight.controller.config.spi.ModuleFactory;
import org.osgi.framework.BundleContext;
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.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
-public class ServiceReferenceRegistryImpl implements ServiceReferenceReadableRegistry, ServiceReferenceWritableRegistry {
+public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceReadableRegistry, ServiceReferenceWritableRegistry {
private static final Logger logger = LoggerFactory.getLogger(ServiceReferenceRegistryImpl.class);
private final Map<String, ModuleFactory> factories;
private final Map<String, Set<String>> factoryNamesToQNames;
// validator of incoming ObjectNames - throws InstanceNotFoundException if not found either in registry or transaction
private final LookupRegistry lookupRegistry;
+ 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;
// all Service Interface qNames for sanity checking
private final Set<String /* qName */> allQNames;
// actual reference database
- private final Map<String /* qName */, Map<String /* refName */, ModuleIdentifier>> refNames;
+ private final Map<ServiceReference, ModuleIdentifier> refNames = new HashMap<>();
+ private final boolean writable;
+ private final Map<ServiceReference, Entry<ServiceReferenceMXBeanImpl, ServiceReferenceJMXRegistration>> mBeans = new HashMap<>();
/**
* Static constructor for config registry. Since only transaction can write to this registry, it will
* return blank state.
*/
- public static ServiceReferenceReadableRegistry createInitialSRLookupRegistry() {
+ public static CloseableServiceReferenceReadableRegistry createInitialSRLookupRegistry() {
// since this is initial state, just throw exception:
LookupRegistry lookupRegistry = new LookupRegistry() {
@Override
@Override
public void checkConfigBeanExists(ObjectName objectName) throws InstanceNotFoundException {
- throw new InstanceNotFoundException("Cannot find " + objectName);
+ throw new InstanceNotFoundException("Cannot find " + objectName + " - Tried to use mocking registry");
}
@Override
public Set<String> getAvailableModuleFactoryQNames() {
throw new UnsupportedOperationException();
}
+
+ @Override
+ public String toString() {
+ return "initial";
+ }
+ };
+ ServiceReferenceTransactionRegistratorFactory serviceReferenceRegistratorFactory = new ServiceReferenceTransactionRegistratorFactory(){
+ @Override
+ public ServiceReferenceRegistrator create() {
+ return new ServiceReferenceRegistrator() {
+ @Override
+ public String getNullableTransactionName() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public ServiceReferenceJMXRegistration registerMBean(ServiceReferenceMXBeanImpl object, ObjectName on) throws InstanceAlreadyExistsException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void close() {
+
+ }
+ };
+ }
};
return new ServiceReferenceRegistryImpl(Collections.<String, ModuleFactory>emptyMap(), lookupRegistry,
- Collections.<String /* qName */, Map<String /* refName */, ModuleIdentifier>>emptyMap());
+ serviceReferenceRegistratorFactory, false);
}
/**
* Static constructor for transaction controller. Take current state as seen by config registry, allow writing new data.
*/
public static ServiceReferenceWritableRegistry createSRWritableRegistry(ServiceReferenceReadableRegistry oldReadableRegistry,
- LookupRegistry lookupRegistry, Map<String, Map.Entry<ModuleFactory, BundleContext>> currentlyRegisteredFactories) {
+ ConfigTransactionLookupRegistry txLookupRegistry,
+ Map<String, Map.Entry<ModuleFactory, BundleContext>> currentlyRegisteredFactories) {
+ if (txLookupRegistry == null) {
+ throw new IllegalArgumentException("txLookupRegistry is null");
+ }
ServiceReferenceRegistryImpl old = (ServiceReferenceRegistryImpl) oldReadableRegistry;
Map<String, ModuleFactory> factories = extractFactoriesMap(currentlyRegisteredFactories);
- return new ServiceReferenceRegistryImpl(factories, lookupRegistry, Collections.unmodifiableMap(old.refNames));
+ ServiceReferenceTransactionRegistratorFactory serviceReferenceRegistratorFactory = new ServiceReferenceTransactionRegistratorFactoryImpl(
+ txLookupRegistry.getTxModuleJMXRegistrator(), txLookupRegistry.getTxModuleJMXRegistrator().getTransactionName());
+ ServiceReferenceRegistryImpl newRegistry = new ServiceReferenceRegistryImpl(factories, txLookupRegistry,
+ serviceReferenceRegistratorFactory, true);
+ copy(old, newRegistry, txLookupRegistry.getTransactionIdentifier().getName());
+ return newRegistry;
}
/**
* Copy back state to config registry after commit.
*/
- public static ServiceReferenceReadableRegistry createSRReadableRegistry(ServiceReferenceWritableRegistry oldWritableRegistry, LookupRegistry lookupRegistry) {
+ public static CloseableServiceReferenceReadableRegistry createSRReadableRegistry(ServiceReferenceWritableRegistry oldWritableRegistry,
+ LookupRegistry lookupRegistry, BaseJMXRegistrator baseJMXRegistrator) {
ServiceReferenceRegistryImpl old = (ServiceReferenceRegistryImpl) oldWritableRegistry;
+
// even if factories do change, nothing in the mapping can change between transactions
- return new ServiceReferenceRegistryImpl(old.factories, lookupRegistry, Collections.unmodifiableMap(old.refNames));
+ ServiceReferenceTransactionRegistratorFactory serviceReferenceRegistratorFactory = new ServiceReferenceTransactionRegistratorFactoryImpl(baseJMXRegistrator);
+ ServiceReferenceRegistryImpl newRegistry = new ServiceReferenceRegistryImpl(old.factories, lookupRegistry,
+ serviceReferenceRegistratorFactory, false);
+ copy(old, newRegistry, null);
+ return newRegistry;
+ }
+
+ /**
+ * Fill refNames and mBeans maps from old instance
+ */
+ private static void copy(ServiceReferenceRegistryImpl old, ServiceReferenceRegistryImpl newRegistry, String nullableDstTransactionName) {
+ for (Entry<ServiceReference, Entry<ServiceReferenceMXBeanImpl, ServiceReferenceJMXRegistration>> refNameEntry : old.mBeans.entrySet()) {
+ ObjectName currentImplementation;
+ ObjectName currentImplementationSrc = refNameEntry.getValue().getKey().getCurrentImplementation();
+ if (nullableDstTransactionName != null) {
+ currentImplementation = ObjectNameUtil.withTransactionName(currentImplementationSrc, nullableDstTransactionName);
+ } else {
+ currentImplementation = ObjectNameUtil.withoutTransactionName(currentImplementationSrc);
+ }
+ try {
+ boolean skipChecks = true;
+ newRegistry.saveServiceReference(refNameEntry.getKey(), currentImplementation, skipChecks);
+ } catch (InstanceNotFoundException e) {
+ logger.error("Cannot save service reference({}, {})", refNameEntry.getKey(), currentImplementation);
+ throw new IllegalStateException("Possible code error", e);
+ }
+ }
}
private static Map<String, ModuleFactory> extractFactoriesMap(Map<String, Map.Entry<ModuleFactory, BundleContext>> currentlyRegisteredFactories) {
}
private ServiceReferenceRegistryImpl(Map<String, ModuleFactory> factories, LookupRegistry lookupRegistry,
- Map<String /* qName */, Map<String /* refName */, ModuleIdentifier>> refNamesToCopy) {
+ ServiceReferenceTransactionRegistratorFactory serviceReferenceRegistratorFactory,
+ boolean writable) {
this.factories = factories;
+ this.writable = writable;
this.lookupRegistry = lookupRegistry;
+
+ this.serviceReferenceRegistrator = serviceReferenceRegistratorFactory.create();
+
Map<String, Set<String /* QName */>> factoryNamesToQNames = new HashMap<>();
Set<ServiceInterfaceAnnotation> allAnnotations = new HashSet<>();
Set<String /* qName */> allQNames = new HashSet<>();
}
this.namespacesToAnnotations = Collections.unmodifiableMap(namespacesToAnnotations);
// copy refNames
- Map<String /* qName */, Map<String /* refName */, ModuleIdentifier>> deepCopy = new HashMap<>();
- for (Entry<String, Map<String, ModuleIdentifier>> outerROEntry: refNamesToCopy.entrySet()) {
- Map<String /* refName */, ModuleIdentifier> innerWritableMap = new HashMap<>();
- deepCopy.put(outerROEntry.getKey(), innerWritableMap);
- for (Entry<String, ModuleIdentifier> innerROEntry: outerROEntry.getValue().entrySet()) {
- innerWritableMap.put(innerROEntry.getKey(), innerROEntry.getValue());
- }
- }
- this.refNames = deepCopy;
logger.trace("factoryNamesToQNames:{}", this.factoryNamesToQNames);
- logger.trace("refNames:{}", refNames);
}
@Override
- public Set<String> lookupServiceInterfaceNames(ObjectName objectName) throws InstanceNotFoundException {
+ public synchronized Set<String> lookupServiceInterfaceNames(ObjectName objectName) throws InstanceNotFoundException {
lookupRegistry.checkConfigBeanExists(objectName);
String factoryName = ObjectNameUtil.getFactoryName(objectName);
}
@Override
- public String getServiceInterfaceName(String namespace, String localName) {
+ public synchronized String getServiceInterfaceName(String namespace, String localName) {
Map<String /* localName */, ServiceInterfaceAnnotation> ofNamespace = namespacesToAnnotations.get(namespace);
if (ofNamespace == null) {
logger.error("Cannot find namespace {} in {}", namespace, namespacesToAnnotations);
return sia.value();
}
-
-
// reading:
@Override
- public Map<String /* serviceInterfaceName */, Map<String/* refName */, ObjectName>> getServiceMapping() {
+ public synchronized Map<String /* serviceInterfaceName */, Map<String/* refName */, ObjectName>> getServiceMapping() {
Map<String /* serviceInterfaceName */, Map<String/* refName */, ObjectName>> result = new HashMap<>();
- for (Entry<String /* qName */, Map<String, ModuleIdentifier>> outerEntry: refNames.entrySet()) {
- String qName = outerEntry.getKey();
- Map<String /* refName */, ObjectName> innerMap = new HashMap<>();
- result.put(qName, innerMap);
- for (Entry<String /* refName */, ModuleIdentifier> innerEntry: outerEntry.getValue().entrySet()) {
- ModuleIdentifier moduleIdentifier = innerEntry.getValue();
- ObjectName on;
- on = getObjectName(moduleIdentifier);
- innerMap.put(innerEntry.getKey(), on);
+ for (Entry<ServiceReference, ModuleIdentifier> entry: refNames.entrySet()) {
+ String qName = entry.getKey().getServiceInterfaceName();
+ Map<String /* refName */, ObjectName> innerMap = result.get(qName);
+ if (innerMap == null) {
+ innerMap = new HashMap<>();
+ result.put(qName, innerMap);
}
+ innerMap.put(entry.getKey().getRefName(), getObjectName(entry.getValue()));
}
return result;
}
}
@Override
- public ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceName, String refName) {
- Map<String, ModuleIdentifier> innerMap = refNames.get(serviceInterfaceName);
- if (innerMap == null) {
- logger.error("Cannot find qname {} in {}", serviceInterfaceName, refName);
- throw new IllegalArgumentException("Cannot find " + serviceInterfaceName);
- }
- ModuleIdentifier moduleIdentifier = innerMap.get(refName);
+ public synchronized ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceQName, String refName) {
+ ServiceReference serviceReference = new ServiceReference(serviceInterfaceQName, refName);
+ ModuleIdentifier moduleIdentifier = refNames.get(serviceReference);
if (moduleIdentifier == null) {
- logger.error("Cannot find refName {} in {}, using qname {}", refName, innerMap, serviceInterfaceName);
- throw new IllegalArgumentException("Cannot find module based on service reference " + refName);
+ logger.error("Cannot find qname {} and refName {} in {}", serviceInterfaceQName, refName, refName);
+ throw new IllegalArgumentException("Cannot find " + serviceReference);
}
return getObjectName(moduleIdentifier);
}
@Override
- public Map<String /* refName */, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName) {
- Map<String, ModuleIdentifier> innerMap = refNames.get(serviceInterfaceName);
+ public synchronized Map<String /* refName */, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceQName) {
+ Map<String, Map<String, ObjectName>> serviceMapping = getServiceMapping();
+ Map<String, ObjectName> innerMap = serviceMapping.get(serviceInterfaceQName);
if (innerMap == null) {
- logger.error("Cannot find qname {} in {}", serviceInterfaceName, refNames);
- throw new IllegalArgumentException("Cannot find " + serviceInterfaceName);
+ logger.error("Cannot find qname {} in {}", serviceInterfaceQName, refNames);
+ throw new IllegalArgumentException("Cannot find " + serviceInterfaceQName);
}
- Map<String /* refName */, ObjectName> result = new HashMap<>();
- for (Entry<String/* refName */, ModuleIdentifier> entry: innerMap.entrySet()) {
- ObjectName on = getObjectName(entry.getValue());
- result.put(entry.getKey(), on);
+ return innerMap;
+ }
+
+ @Override
+ public synchronized ObjectName getServiceReference(String serviceInterfaceQName, String refName) throws InstanceNotFoundException {
+ ServiceReference serviceReference = new ServiceReference(serviceInterfaceQName, refName);
+ if (mBeans.containsKey(serviceReference) == false) {
+ throw new InstanceNotFoundException("Cannot find " + serviceReference);
+ }
+ return getServiceON(serviceReference);
+ }
+
+ @Override
+ public synchronized void checkServiceReferenceExists(ObjectName objectName) throws InstanceNotFoundException {
+ String actualTransactionName = ObjectNameUtil.getTransactionName(objectName);
+ String expectedTransactionName = serviceReferenceRegistrator.getNullableTransactionName();
+ if (writable & actualTransactionName == null || (writable && actualTransactionName.equals(expectedTransactionName) == false)) {
+ throw new IllegalArgumentException("Mismatched transaction name in " + objectName);
+ }
+ String serviceQName = ObjectNameUtil.getServiceQName(objectName);
+ String referenceName = ObjectNameUtil.getReferenceName(objectName);
+ ServiceReference serviceReference = new ServiceReference(serviceQName, referenceName);
+ if (refNames.containsKey(serviceReference) == false) {
+ logger.warn("Cannot find {} in {}", serviceReference, refNames);
+ throw new InstanceNotFoundException("Service reference not found:" + objectName);
}
- return result;
}
// writing:
+ private void assertWritable() {
+ if (writable == false) {
+ throw new IllegalStateException("Cannot write to readable registry");
+ }
+ }
+
@Override
- public void saveServiceReference(String serviceInterfaceName, String refName, ObjectName objectName) throws InstanceNotFoundException {
+ public synchronized ObjectName saveServiceReference(String serviceInterfaceName, String refName, ObjectName moduleON) throws InstanceNotFoundException {
+ assertWritable();
+ ServiceReference serviceReference = new ServiceReference(serviceInterfaceName, refName);
+ return saveServiceReference(serviceReference, moduleON);
+ }
+
+ private synchronized ObjectName saveServiceReference(ServiceReference serviceReference, ObjectName moduleON)
+ throws InstanceNotFoundException{
+ return saveServiceReference(serviceReference, moduleON, false);
+ }
+
+ private synchronized ObjectName saveServiceReference(ServiceReference serviceReference, ObjectName moduleON,
+ boolean skipChecks) throws InstanceNotFoundException {
+
// make sure it is found
- lookupRegistry.checkConfigBeanExists(objectName);
- String factoryName = ObjectNameUtil.getFactoryName(objectName);
+ if (skipChecks == false) {
+ lookupRegistry.checkConfigBeanExists(moduleON);
+ }
+ String factoryName = ObjectNameUtil.getFactoryName(moduleON);
+ String instanceName = ObjectNameUtil.getInstanceName(moduleON);
+ ModuleIdentifier moduleIdentifier = new ModuleIdentifier(factoryName, instanceName);
+
// check that service interface name exist
- Set<String> serviceInterfaceQNames = factoryNamesToQNames.get(factoryName);
+ Set<String> serviceInterfaceQNames = factoryNamesToQNames.get(moduleIdentifier.getFactoryName());
if (serviceInterfaceQNames == null) {
- logger.error("Possible error in code: cannot find factoryName {} in {}, object name {}", factoryName, factoryNamesToQNames, objectName);
- throw new IllegalStateException("Possible error in code: cannot find annotations of existing factory " + factoryName);
+ logger.error("Possible error in code: cannot find factoryName {} in {}, {}", moduleIdentifier.getFactoryName(),
+ factoryNamesToQNames, moduleIdentifier);
+ 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(serviceInterfaceName) == false) {
- logger.error("Cannot find qname {} with factory name {}, found {}", serviceInterfaceName, factoryName, serviceInterfaceQNames);
- throw new IllegalArgumentException("Cannot find service interface " + serviceInterfaceName + " within factory " + factoryName );
+ 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());
}
- String instanceName = ObjectNameUtil.getInstanceName(objectName);
- ModuleIdentifier moduleIdentifier = new ModuleIdentifier(factoryName, instanceName);
- Map<String /* refName */, ModuleIdentifier> ofQName = refNames.get(serviceInterfaceName);
- // might be null
- if (ofQName == null) {
- ofQName = new HashMap<>();
- refNames.put(serviceInterfaceName, ofQName);
+
+
+ // create service reference object name, put to mBeans
+ ObjectName result = getServiceON(serviceReference);
+ Entry<ServiceReferenceMXBeanImpl, ServiceReferenceJMXRegistration> mxBeanEntry = mBeans.get(serviceReference);
+ if (mxBeanEntry == null) {
+ // create dummy mx bean
+ ServiceReferenceMXBeanImpl dummyMXBean = new ServiceReferenceMXBeanImpl(moduleON);
+ ServiceReferenceJMXRegistration dummyMXBeanRegistration;
+ try {
+ dummyMXBeanRegistration = serviceReferenceRegistrator.registerMBean(dummyMXBean, result);
+ } catch (InstanceAlreadyExistsException e) {
+ throw new IllegalStateException("Possible error in code. Cannot register " + result, e);
+ }
+ mBeans.put(serviceReference, createMXBeanEntry(dummyMXBean, dummyMXBeanRegistration));
+ } else {
+ // update
+ mxBeanEntry.getKey().setCurrentImplementation(moduleON);
+ }
+ // save to refNames
+ refNames.put(serviceReference, moduleIdentifier);
+ return result;
+ }
+
+ private Entry<ServiceReferenceMXBeanImpl, ServiceReferenceJMXRegistration> createMXBeanEntry(
+ final ServiceReferenceMXBeanImpl mxBean, final ServiceReferenceJMXRegistration registration) {
+ return new Entry<ServiceReferenceMXBeanImpl, ServiceReferenceJMXRegistration>() {
+ @Override
+ public ServiceReferenceMXBeanImpl getKey() {
+ return mxBean;
+ }
+
+ @Override
+ public ServiceReferenceJMXRegistration getValue() {
+ return registration;
+ }
+
+ @Override
+ public ServiceReferenceJMXRegistration setValue(ServiceReferenceJMXRegistration value) {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+
+ private ObjectName getServiceON(ServiceReference serviceReference) {
+ if (writable) {
+ return ObjectNameUtil.createTransactionServiceON(serviceReferenceRegistrator.getNullableTransactionName(),
+ serviceReference.getServiceInterfaceName(), serviceReference.getRefName());
+ } else {
+ return ObjectNameUtil.createReadOnlyServiceON(serviceReference.getServiceInterfaceName(), serviceReference.getRefName());
}
- ofQName.put(refName, moduleIdentifier);
}
@Override
- public boolean removeServiceReference(String serviceInterfaceName, String refName) {
- // is the qname known?
- if (allQNames.contains(serviceInterfaceName) == false) {
- logger.error("Cannot find qname {} in {}", serviceInterfaceName, allQNames);
- throw new IllegalArgumentException("Cannot find service interface " + serviceInterfaceName);
+ public synchronized void removeServiceReference(String serviceInterfaceName, String refName) throws InstanceNotFoundException{
+ ServiceReference serviceReference = new ServiceReference(serviceInterfaceName, refName);
+ removeServiceReference(serviceReference);
+ }
+
+ private synchronized void removeServiceReference(ServiceReference serviceReference) throws InstanceNotFoundException {
+ 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());
+ }
+ ModuleIdentifier removed = refNames.remove(serviceReference);
+ if (removed == null){
+ throw new InstanceNotFoundException("Cannot find " + serviceReference.getServiceInterfaceName());
}
- Map<String, ModuleIdentifier> ofQName = refNames.get(serviceInterfaceName);
- if (ofQName == null) {
- return false;
+ Entry<ServiceReferenceMXBeanImpl, ServiceReferenceJMXRegistration> entry = mBeans.remove(serviceReference);
+ if (entry == null) {
+ throw new IllegalStateException("Possible code error: cannot remove from mBeans: " + serviceReference);
}
- return ofQName.remove(refName) != null;
+ entry.getValue().close();
}
@Override
- public void removeAllServiceReferences() {
- refNames.clear();
+ public synchronized void removeAllServiceReferences() {
+ assertWritable();
+ for (ServiceReference serviceReference: mBeans.keySet()) {
+ try {
+ removeServiceReference(serviceReference);
+ } catch (InstanceNotFoundException e) {
+ throw new IllegalStateException("Possible error in code", e);
+ }
+ }
}
@Override
- public boolean removeServiceReferences(ObjectName objectName) throws InstanceNotFoundException {
- lookupRegistry.checkConfigBeanExists(objectName);
- String factoryName = ObjectNameUtil.getFactoryName(objectName);
+ public synchronized boolean removeServiceReferences(ObjectName moduleObjectName) throws InstanceNotFoundException {
+ assertWritable();
+ Set<ServiceReference> serviceReferencesLinkingTo = findServiceReferencesLinkingTo(moduleObjectName);
+ for (ServiceReference sr : serviceReferencesLinkingTo) {
+ removeServiceReference(sr);
+ }
+ return serviceReferencesLinkingTo.isEmpty() == false;
+ }
+
+ private synchronized Set<ServiceReference> findServiceReferencesLinkingTo(ObjectName moduleObjectName) throws InstanceNotFoundException {
+ lookupRegistry.checkConfigBeanExists(moduleObjectName);
+ 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, objectName);
+ logger.error("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(objectName);
+ String instanceName = ObjectNameUtil.getInstanceName(moduleObjectName);
ModuleIdentifier moduleIdentifier = new ModuleIdentifier(factoryName, instanceName);
- boolean found = false;
- for(String qName: serviceInterfaceQNames){
- Map<String, ModuleIdentifier> ofQName = refNames.get(qName);
- if (ofQName != null) {
- for(Iterator<Entry<String, ModuleIdentifier>> it = ofQName.entrySet ().iterator(); it.hasNext();){
- Entry<String, ModuleIdentifier> next = it.next();
- if (next.getValue().equals(moduleIdentifier)) {
- found = true;
- it.remove();
- }
- }
+ Set<ServiceReference> result = new HashSet<>();
+ for (Entry<ServiceReference, ModuleIdentifier> entry : refNames.entrySet()) {
+ if (entry.getValue().equals(moduleIdentifier)) {
+ result.add(entry.getKey());
}
}
- return found;
+ return result;
}
+
@Override
public String toString() {
return "ServiceReferenceRegistryImpl{" +
+ "lookupRegistry=" + lookupRegistry +
"refNames=" + refNames +
", factoryNamesToQNames=" + factoryNamesToQNames +
'}';
}
+
+ @Override
+ public void close() {
+ serviceReferenceRegistrator.close();
+ }
}
import org.opendaylight.controller.config.api.JmxAttribute;
import org.opendaylight.controller.config.api.JmxAttributeValidationException;
import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
import org.opendaylight.controller.config.api.annotations.AbstractServiceInterface;
import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
import org.opendaylight.controller.config.manager.impl.TransactionStatus;
private final TransactionStatus transactionStatus;
@GuardedBy("this")
private final Set<ModuleIdentifier> dependencies = new HashSet<>();
+ private final ServiceReferenceReadableRegistry readableRegistry;
DependencyResolverImpl(ModuleIdentifier currentModule,
- TransactionStatus transactionStatus, ModulesHolder modulesHolder) {
+ TransactionStatus transactionStatus, ModulesHolder modulesHolder,
+ ServiceReferenceReadableRegistry readableRegistry) {
+
this.name = currentModule;
this.transactionStatus = transactionStatus;
this.modulesHolder = modulesHolder;
+ this.readableRegistry = readableRegistry;
}
/**
@Override
public void validateDependency(
Class<? extends AbstractServiceInterface> expectedServiceInterface,
- ObjectName dependentModuleReadOnlyON, JmxAttribute jmxAttribute) {
+ ObjectName dependentReadOnlyON, JmxAttribute jmxAttribute) {
transactionStatus.checkNotCommitted();
if (expectedServiceInterface == null) {
if (jmxAttribute == null)
throw new NullPointerException("Parameter 'jmxAttribute' is null");
- JmxAttributeValidationException.checkNotNull(dependentModuleReadOnlyON,
+ JmxAttributeValidationException.checkNotNull(dependentReadOnlyON,
"is null, " + "expected dependency implementing "
+ expectedServiceInterface, jmxAttribute);
+
+
// check that objectName belongs to this transaction - this should be
// stripped
// in DynamicWritableWrapper
boolean hasTransaction = ObjectNameUtil
- .getTransactionName(dependentModuleReadOnlyON) != null;
+ .getTransactionName(dependentReadOnlyON) != null;
JmxAttributeValidationException.checkCondition(
hasTransaction == false,
format("ObjectName should not contain "
+ "transaction name. %s set to %s. ", jmxAttribute,
- dependentModuleReadOnlyON), jmxAttribute);
+ dependentReadOnlyON), jmxAttribute);
+
+ dependentReadOnlyON = translateServiceRefIfPossible(dependentReadOnlyON);
- ModuleIdentifier moduleIdentifier = ObjectNameUtil.fromON(dependentModuleReadOnlyON, ObjectNameUtil
+ ModuleIdentifier moduleIdentifier = ObjectNameUtil.fromON(dependentReadOnlyON, ObjectNameUtil
.TYPE_MODULE);
ModuleFactory foundFactory = modulesHolder.findModuleFactory(moduleIdentifier, jmxAttribute);
+ "Module name is %s : %s, expected service interface %s, dependent module ON %s , "
+ "attribute %s",
foundFactory.getImplementationName(), foundFactory,
- expectedServiceInterface, dependentModuleReadOnlyON,
+ expectedServiceInterface, dependentReadOnlyON,
jmxAttribute);
throw new JmxAttributeValidationException(message, jmxAttribute);
}
}
}
+ // transalate from serviceref to module ON
+ private ObjectName translateServiceRefIfPossible(ObjectName dependentReadOnlyON) {
+ if (ObjectNameUtil.isServiceReference(dependentReadOnlyON)) {
+ String serviceQName = ObjectNameUtil.getServiceQName(dependentReadOnlyON);
+ String refName = ObjectNameUtil.getReferenceName(dependentReadOnlyON);
+ dependentReadOnlyON = ObjectNameUtil.withoutTransactionName( // strip again of transaction name
+ readableRegistry.lookupConfigBeanByServiceInterfaceName(serviceQName, refName));
+ }
+ return dependentReadOnlyON;
+ }
+
/**
* {@inheritDoc}
*/
//TODO: check for cycles
@Override
- public <T> T resolveInstance(Class<T> expectedType, ObjectName dependentON,
+ public <T> T resolveInstance(Class<T> expectedType, ObjectName dependentReadOnlyON,
JmxAttribute jmxAttribute) {
- if (expectedType == null || dependentON == null || jmxAttribute == null) {
+ if (expectedType == null || dependentReadOnlyON == null || jmxAttribute == null) {
throw new IllegalArgumentException(format(
"Null parameters not allowed, got {} {} {}", expectedType,
- dependentON, jmxAttribute));
+ dependentReadOnlyON, jmxAttribute));
}
-
+ dependentReadOnlyON = translateServiceRefIfPossible(dependentReadOnlyON);
transactionStatus.checkCommitStarted();
transactionStatus.checkNotCommitted();
ModuleIdentifier dependentModuleIdentifier = ObjectNameUtil.fromON(
- dependentON, ObjectNameUtil.TYPE_MODULE);
+ dependentReadOnlyON, ObjectNameUtil.TYPE_MODULE);
Module module = modulesHolder.findModule(dependentModuleIdentifier,
jmxAttribute);
synchronized (this) {
import org.opendaylight.controller.config.api.DependencyResolverFactory;
import org.opendaylight.controller.config.api.JmxAttribute;
import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
import org.opendaylight.controller.config.manager.impl.CommitInfo;
import org.opendaylight.controller.config.manager.impl.ModuleInternalTransactionalInfo;
import org.opendaylight.controller.config.manager.impl.TransactionStatus;
private final Map<ModuleIdentifier, DependencyResolverImpl> moduleIdentifiersToDependencyResolverMap = new HashMap<>();
private final ModulesHolder modulesHolder;
private final TransactionStatus transactionStatus;
+ private final ServiceReferenceReadableRegistry readableRegistry;
public DependencyResolverManager(String transactionName,
- TransactionStatus transactionStatus) {
+ TransactionStatus transactionStatus, ServiceReferenceReadableRegistry readableRegistry) {
this.modulesHolder = new ModulesHolder(transactionName);
this.transactionStatus = transactionStatus;
+ this.readableRegistry = readableRegistry;
}
@Override
}
public synchronized DependencyResolverImpl getOrCreate(ModuleIdentifier name) {
- DependencyResolverImpl dependencyResolver = moduleIdentifiersToDependencyResolverMap
- .get(name);
+ DependencyResolverImpl dependencyResolver = moduleIdentifiersToDependencyResolverMap.get(name);
if (dependencyResolver == null) {
transactionStatus.checkNotCommitted();
- dependencyResolver = new DependencyResolverImpl(name,
- transactionStatus, modulesHolder);
- moduleIdentifiersToDependencyResolverMap.put(name,
- dependencyResolver);
+ dependencyResolver = new DependencyResolverImpl(name, transactionStatus, modulesHolder, readableRegistry);
+ moduleIdentifiersToDependencyResolverMap.put(name, dependencyResolver);
}
return dependencyResolver;
}
import javax.management.QueryExp;
import java.util.Set;
-public class BaseJMXRegistrator implements AutoCloseable {
+public class BaseJMXRegistrator implements AutoCloseable, NestableJMXRegistrator {
private final InternalJMXRegistrator internalJMXRegistrator;
return internalJMXRegistrator.getRegisteredObjectNames();
}
+ @Override
+ public InternalJMXRegistrator createChild() {
+ return internalJMXRegistrator.createChild();
+ }
+
@Override
public void close() {
internalJMXRegistrator.close();
--- /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.jmx;
+
+public interface NestableJMXRegistrator {
+
+ InternalJMXRegistrator createChild();
+}
--- /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.jmx;
+
+public class ServiceReference {
+ private final String serviceInterfaceName, refName;
+
+ public ServiceReference(String serviceInterfaceName, String refName) {
+ this.serviceInterfaceName = serviceInterfaceName;
+ this.refName = refName;
+ }
+
+ public String getServiceInterfaceName() {
+ return serviceInterfaceName;
+ }
+
+ public String getRefName() {
+ return refName;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ ServiceReference that = (ServiceReference) o;
+
+ if (!refName.equals(that.refName)) return false;
+ if (!serviceInterfaceName.equals(that.serviceInterfaceName)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = serviceInterfaceName.hashCode();
+ result = 31 * result + refName.hashCode();
+ return result;
+ }
+}
--- /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.jmx;
+
+import javax.management.ObjectName;
+
+public interface ServiceReferenceMXBean {
+
+ ObjectName getCurrentImplementation();
+
+}
--- /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.jmx;
+
+import javax.management.ObjectName;
+
+public class ServiceReferenceMXBeanImpl implements ServiceReferenceMXBean {
+ private ObjectName currentImplementation;
+
+ public ServiceReferenceMXBeanImpl(ObjectName currentImplementation) {
+ this.currentImplementation = currentImplementation;
+ }
+
+ @Override
+ public ObjectName getCurrentImplementation() {
+ return currentImplementation;
+ }
+
+ public void setCurrentImplementation(ObjectName currentImplementation) {
+ this.currentImplementation = currentImplementation;
+ }
+}
--- /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.jmx;
+
+import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
+import org.opendaylight.controller.config.manager.impl.jmx.InternalJMXRegistrator.InternalJMXRegistration;
+
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.ObjectName;
+
+public interface ServiceReferenceRegistrator extends AutoCloseable {
+
+ public String getNullableTransactionName();
+
+ ServiceReferenceJMXRegistration registerMBean(ServiceReferenceMXBeanImpl object,
+ ObjectName on) throws InstanceAlreadyExistsException;
+
+ @Override
+ void close();
+
+ public static class ServiceReferenceJMXRegistration implements AutoCloseable {
+ private final InternalJMXRegistration registration;
+
+ ServiceReferenceJMXRegistration(InternalJMXRegistration registration) {
+ this.registration = registration;
+ }
+
+ @Override
+ public void close() {
+ registration.close();
+ }
+ }
+
+ public static interface ServiceReferenceTransactionRegistratorFactory {
+ public ServiceReferenceRegistrator create();
+ }
+
+ public static class ServiceReferenceRegistratorImpl implements ServiceReferenceRegistrator {
+ private final InternalJMXRegistrator currentJMXRegistrator;
+ private final String nullableTransactionName;
+
+ public ServiceReferenceRegistratorImpl(NestableJMXRegistrator parentRegistrator, String nullableTransactionName){
+ currentJMXRegistrator = parentRegistrator.createChild();
+ this.nullableTransactionName = nullableTransactionName;
+ }
+
+ public String getNullableTransactionName() {
+ return nullableTransactionName;
+ }
+
+
+ public ServiceReferenceJMXRegistration registerMBean(ServiceReferenceMXBeanImpl object,
+ ObjectName on) throws InstanceAlreadyExistsException {
+ String actualTransactionName = ObjectNameUtil.getTransactionName(on);
+ boolean broken = false;
+ broken |= (nullableTransactionName == null) != (actualTransactionName == null);
+ broken |= (nullableTransactionName != null) && nullableTransactionName.equals(actualTransactionName) == false;
+ if (broken) {
+ throw new IllegalArgumentException("Transaction name mismatch between expected "
+ + nullableTransactionName + ", got " + actualTransactionName + " in " + on);
+ }
+ if (ObjectNameUtil.isServiceReference(on) == false) {
+ throw new IllegalArgumentException("Invalid type of " + on);
+ }
+ return new ServiceReferenceJMXRegistration(currentJMXRegistrator.registerMBean(object, on));
+ }
+
+
+ @Override
+ public void close() {
+ currentJMXRegistrator.close();
+ }
+ public static interface ServiceReferenceTransactionRegistratorFactory {
+ public ServiceReferenceRegistrator create();
+ }
+ }
+
+
+ public static class ServiceReferenceTransactionRegistratorFactoryImpl implements ServiceReferenceTransactionRegistratorFactory {
+ private final NestableJMXRegistrator parentRegistrator;
+ private final String nullableTransactionName;
+
+ public ServiceReferenceTransactionRegistratorFactoryImpl(TransactionModuleJMXRegistrator parentRegistrator,
+ String nullableTransactionName) {
+ this.parentRegistrator = parentRegistrator;
+ this.nullableTransactionName = nullableTransactionName;
+ }
+
+ public ServiceReferenceTransactionRegistratorFactoryImpl(BaseJMXRegistrator baseJMXRegistrator) {
+ this.parentRegistrator = baseJMXRegistrator;
+ this.nullableTransactionName = null;
+ }
+
+ public ServiceReferenceRegistrator create() {
+ return new ServiceReferenceRegistratorImpl(parentRegistrator, nullableTransactionName);
+ }
+ }
+}
import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
import org.opendaylight.controller.config.manager.impl.jmx.InternalJMXRegistrator.InternalJMXRegistration;
-public class TransactionModuleJMXRegistrator implements Closeable {
- private final InternalJMXRegistrator childJMXRegistrator;
+public class TransactionModuleJMXRegistrator implements Closeable, NestableJMXRegistrator {
+ private final InternalJMXRegistrator currentJMXRegistrator;
private final String transactionName;
public TransactionModuleJMXRegistrator(
InternalJMXRegistrator internalJMXRegistrator,
String transactionName) {
- this.childJMXRegistrator = internalJMXRegistrator.createChild();
+ this.currentJMXRegistrator = internalJMXRegistrator.createChild();
this.transactionName = transactionName;
}
public TransactionModuleJMXRegistration registerMBean(Object object,
ObjectName on) throws InstanceAlreadyExistsException {
- if (!transactionName.equals(ObjectNameUtil.getTransactionName(on)))
- throw new IllegalArgumentException(
- "Transaction name mismatch between expected "
+ if (transactionName.equals(ObjectNameUtil.getTransactionName(on)) == false) {
+ throw new IllegalArgumentException("Transaction name mismatch between expected "
+ transactionName + " " + "and " + on);
- ObjectNameUtil.checkType(on, ObjectNameUtil.TYPE_MODULE);
+ }
+ ObjectNameUtil.checkTypeOneOf(on, ObjectNameUtil.TYPE_MODULE);
return new TransactionModuleJMXRegistration(
- childJMXRegistrator.registerMBean(object, on));
+ currentJMXRegistrator.registerMBean(object, on));
}
public Set<ObjectName> queryNames(ObjectName name, QueryExp query) {
- return childJMXRegistrator.queryNames(name, query);
+ return currentJMXRegistrator.queryNames(name, query);
}
@Override
public void close() {
- childJMXRegistrator.close();
+ currentJMXRegistrator.close();
+ }
+
+ public String getTransactionName() {
+ return transactionName;
+ }
+
+ public InternalJMXRegistrator createChild() {
+ return currentJMXRegistrator.createChild();
}
}
import org.opendaylight.controller.config.manager.impl.jmx.BaseJMXRegistrator;
import org.opendaylight.controller.config.manager.impl.jmx.ConfigRegistryJMXRegistrator;
import org.opendaylight.controller.config.manager.impl.jmx.InternalJMXRegistrator;
+import org.opendaylight.controller.config.manager.testingservices.scheduledthreadpool.TestingScheduledThreadPoolImpl;
+import org.opendaylight.controller.config.manager.testingservices.threadpool.TestingFixedThreadPool;
import org.opendaylight.controller.config.spi.Module;
import org.opendaylight.controller.config.util.ConfigRegistryJMXClient;
import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
public final void cleanUpConfigTransactionManagerImpl() {
configRegistryJMXRegistrator.close();
configRegistry.close();
+ TestingFixedThreadPool.cleanUp();
+ TestingScheduledThreadPoolImpl.cleanUp();
}
/**
--- /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 com.google.common.collect.ImmutableMap;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
+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.parallelapsp.test.AbstractParallelAPSPTest;
+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.util.ConfigTransactionJMXClient;
+
+import javax.management.Attribute;
+import javax.management.AttributeNotFoundException;
+import javax.management.InstanceNotFoundException;
+import javax.management.JMX;
+import javax.management.MBeanException;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+
+import java.util.Map;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.opendaylight.controller.config.api.jmx.ObjectNameUtil.withoutTransactionName;
+
+public class ServiceReferenceRegistryImplTest extends AbstractParallelAPSPTest {
+
+
+ @Before
+ public void setUp() {
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(
+ new TestingFixedThreadPoolModuleFactory(),
+ new TestingParallelAPSPModuleFactory(),
+ new TestingScheduledThreadPoolModuleFactory()));
+ }
+
+ @Override
+ protected String getThreadPoolImplementationName() {
+ return TestingFixedThreadPoolModuleFactory.NAME;
+ }
+
+ @Test
+ public void test() throws Exception {
+ ConfigTransactionJMXClient transaction1 = configRegistryClient.createTransaction();
+ // create fixed1
+ int fixedNrOfThreads = 20, scheduledNrOfThreads = 30;
+
+ ObjectName fixedTPTransactionON = transaction1.createModule(getThreadPoolImplementationName(), fixed1);
+ platformMBeanServer.setAttribute(fixedTPTransactionON, new Attribute("ThreadCount", fixedNrOfThreads));
+
+ ObjectName scheduledTPTransactionON = transaction1.createModule(
+ TestingScheduledThreadPoolModuleFactory.NAME, "scheduled1");
+ platformMBeanServer.setAttribute(scheduledTPTransactionON, new Attribute("ThreadCount",
+ scheduledNrOfThreads));
+
+ String refName = "ref";
+ ObjectName serviceReference = transaction1.saveServiceReference(TestingThreadPoolServiceInterface.QNAME, refName,
+ fixedTPTransactionON);
+ // 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);
+
+ // switch reference to scheduled
+ ConfigTransactionJMXClient transaction2 = configRegistryClient.createTransaction();
+ transaction2.saveServiceReference(TestingThreadPoolServiceInterface.QNAME, refName,
+ ObjectNameUtil.withTransactionName(scheduledTPTransactionON, transaction2.getTransactionName()));
+ transaction2.commit();
+ // check scheduled is used
+ checkApspThreadCount(scheduledNrOfThreads);
+ // check that dummy MXBean points to scheduled
+ assertEquals(withoutTransactionName(scheduledTPTransactionON), serviceReferenceMXBean.getCurrentImplementation());
+
+ // empty transaction
+ configRegistryClient.createTransaction().commit();
+
+ // get service mapping
+ Map<String,Map<String,ObjectName>> serviceMapping = configRegistryClient.getServiceMapping();
+ Map<String,Map<String,ObjectName>> expectedMapping = ImmutableMap.of(TestingThreadPoolServiceInterface.QNAME,
+ (Map<String, ObjectName>)ImmutableMap.of(refName, withoutTransactionName(scheduledTPTransactionON)));
+ assertEquals(expectedMapping, serviceMapping);
+
+ // destroy all
+ ConfigTransactionJMXClient transaction4 = configRegistryClient.createTransaction();
+ Set<ObjectName> objectNames = transaction4.lookupConfigBeans();
+ for(ObjectName on: objectNames) {
+ transaction4.destroyModule(on);
+ }
+ transaction4.commit();
+
+ serviceMapping = configRegistryClient.getServiceMapping();
+ assertTrue(serviceMapping.isEmpty());
+ }
+
+ private void checkApspThreadCount(int fixedNrOfThreads) throws MBeanException, AttributeNotFoundException,
+ InstanceNotFoundException, ReflectionException {
+ ObjectName apspON = ObjectNameUtil.createReadOnlyModuleON(TestingParallelAPSPModuleFactory.NAME, apsp1);
+ assertEquals(fixedNrOfThreads, platformMBeanServer.getAttribute(apspON, "MaxNumberOfThreads"));
+ }
+}
import org.junit.Test;
import org.opendaylight.controller.config.api.JmxAttribute;
import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
import org.opendaylight.controller.config.manager.impl.ModuleInternalTransactionalInfo;
import org.opendaylight.controller.config.manager.impl.TransactionStatus;
@Before
public void setUp() {
transactionStatus = mock(TransactionStatus.class);
- tested = new DependencyResolverManager("txName", transactionStatus);
+ ServiceReferenceReadableRegistry mockedRegistry = mock(ServiceReferenceReadableRegistry.class);
+ tested = new DependencyResolverManager("txName", transactionStatus, mockedRegistry);
doNothing().when(transactionStatus).checkCommitStarted();
doNothing().when(transactionStatus).checkNotCommitted();
}
*/
package org.opendaylight.controller.config.manager.impl.util;
-import java.util.Set;
-
-import javax.management.ObjectName;
-
+import com.google.common.base.Throwables;
+import com.google.common.collect.Sets;
import org.junit.After;
import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
import org.opendaylight.controller.config.manager.impl.AbstractLockedPlatformMBeanServerTest;
-import com.google.common.base.Throwables;
-import com.google.common.collect.Sets;
+import javax.management.ObjectName;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
public class ObjectNameUtilTest extends AbstractLockedPlatformMBeanServerTest {
private Set<ObjectName> unregisterONs;
}
}
if (lastException != null) {
- Throwables.propagate(lastException);
+ throw Throwables.propagate(lastException);
}
}
+
+ @Test
+ public void testQuotation() throws Exception {
+ String serviceQName = "(namespace?revision=r)qname";
+ String refName = "refName";
+ String transaction = "transaction";
+ ObjectName serviceReferenceON = ObjectNameUtil.createTransactionServiceON(transaction, serviceQName, refName);
+ assertFalse(serviceReferenceON.isPattern());
+ assertEquals(serviceQName, ObjectNameUtil.getServiceQName(serviceReferenceON));
+ assertEquals(refName, ObjectNameUtil.getReferenceName(serviceReferenceON));
+ assertEquals(transaction, ObjectNameUtil.getTransactionName(serviceReferenceON));
+
+ serviceReferenceON = ObjectNameUtil.createReadOnlyServiceON(serviceQName, refName);
+ assertFalse(serviceReferenceON.isPattern());
+ assertEquals(serviceQName, ObjectNameUtil.getServiceQName(serviceReferenceON));
+ assertEquals(refName, ObjectNameUtil.getReferenceName(serviceReferenceON));
+ assertEquals(null, ObjectNameUtil.getTransactionName(serviceReferenceON));
+
+ }
}
if (oldInstance != null) {
// changing thread pool is not supported
- boolean reuse = threadPoolInstance.equals(oldInstance
- .getThreadPool());
+ boolean reuse = threadPoolInstance == oldInstance.getThreadPool();
if (reuse) {
logger.debug("Reusing old instance");
instance = oldInstance;
import javax.management.InstanceAlreadyExistsException;
import javax.management.ObjectName;
-abstract class AbstractParallelAPSPTest extends AbstractConfigTest {
+public abstract class AbstractParallelAPSPTest extends AbstractConfigTest {
protected final String fixed1 = "fixed1";
protected final String apsp1 = "apsp-parallel";
- abstract String getThreadPoolImplementationName();
+ protected abstract String getThreadPoolImplementationName();
protected ObjectName createParallelAPSP(
ConfigTransactionJMXClient transaction, ObjectName threadPoolON)
protected ObjectName createFixed1(ConfigTransactionJMXClient transaction,
int numberOfThreads) throws InstanceAlreadyExistsException {
+
ObjectName name = transaction.createModule(
getThreadPoolImplementationName(), fixed1);
}
@Override
- String getThreadPoolImplementationName() {
+ protected String getThreadPoolImplementationName() {
return TestingFixedThreadPoolModuleFactory.NAME;
}
}
@Override
- String getThreadPoolImplementationName() {
+ protected String getThreadPoolImplementationName() {
return threadPoolImplementationName;
}
public boolean isRecreate();
public void setRecreate(boolean recreate);
+
+ public void setThreadCount(int threadCount);
+
}
@Nullable
private final TestingScheduledThreadPoolImpl oldInstance;
- private final int threadCount = 10;
+ private int threadCount = 10;
private TestingScheduledThreadPoolImpl instance;
private RootRuntimeBeanRegistrator runtimeBeanRegistrator;
private boolean recreate;
return threadCount;
}
+ @Override
+ public void setThreadCount(int threadCount) {
+ this.threadCount = threadCount;
+ }
+
@Override
public Closeable getInstance() {
assertNotNull(runtimeBeanRegistrator);
import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation;
import org.opendaylight.controller.config.manager.testingservices.threadpool.TestingThreadPoolIfc;
-@ServiceInterfaceAnnotation(value = "testing-threadpool", osgiRegistrationType = TestingThreadPoolIfc.class,
- namespace = "ns", revision = "foo", localName = "bar")
+@ServiceInterfaceAnnotation(value = TestingThreadPoolServiceInterface.QNAME, osgiRegistrationType = TestingThreadPoolIfc.class,
+ namespace = "ns", revision = "foo", localName = "testing-threadpool")
public interface TestingThreadPoolServiceInterface extends
AbstractServiceInterface {
+ public static final String QNAME = "(ns?revision=foo)testing-threadpool";
}
}
@Override
- public ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceName, String refName) {
- return configRegistryMXBeanProxy.lookupConfigBeanByServiceInterfaceName(serviceInterfaceName, refName);
+ public ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceQName, String refName) {
+ return configRegistryMXBeanProxy.lookupConfigBeanByServiceInterfaceName(serviceInterfaceQName, refName);
}
@Override
}
@Override
- public Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName) {
- return configRegistryMXBeanProxy.lookupServiceReferencesByServiceInterfaceName(serviceInterfaceName);
+ public Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceQName) {
+ return configRegistryMXBeanProxy.lookupServiceReferencesByServiceInterfaceName(serviceInterfaceQName);
}
@Override
public Set<String> getAvailableModuleFactoryQNames() {
return configRegistryMXBeanProxy.getAvailableModuleFactoryQNames();
}
+
+ @Override
+ public ObjectName getServiceReference(String serviceInterfaceQName, String refName) throws InstanceNotFoundException {
+ return configRegistryMXBeanProxy.getServiceReference(serviceInterfaceQName, refName);
+ }
+
+ @Override
+ public void checkServiceReferenceExists(ObjectName objectName) throws InstanceNotFoundException {
+ configRegistryMXBeanProxy.checkServiceReferenceExists(objectName);
+ }
+
}
}
@Override
- public void saveServiceReference(String serviceInterfaceName, String refName, ObjectName objectName) throws InstanceNotFoundException {
- configTransactionControllerMXBeanProxy.saveServiceReference(serviceInterfaceName,refName,objectName);
+ public ObjectName saveServiceReference(String serviceInterfaceName, String refName, ObjectName moduleON) throws InstanceNotFoundException {
+ return configTransactionControllerMXBeanProxy.saveServiceReference(serviceInterfaceName,refName, moduleON);
}
@Override
- public boolean removeServiceReference(String serviceInterfaceName, String refName) {
- return configTransactionControllerMXBeanProxy.removeServiceReference(serviceInterfaceName, refName);
+ public void removeServiceReference(String serviceInterfaceName, String refName) throws InstanceNotFoundException{
+ configTransactionControllerMXBeanProxy.removeServiceReference(serviceInterfaceName, refName);
}
@Override
}
@Override
- public ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceName, String refName) {
- return configTransactionControllerMXBeanProxy.lookupConfigBeanByServiceInterfaceName(serviceInterfaceName, refName);
+ public ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceQName, String refName) {
+ return configTransactionControllerMXBeanProxy.lookupConfigBeanByServiceInterfaceName(serviceInterfaceQName, refName);
}
@Override
}
@Override
- public Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName) {
- return configTransactionControllerMXBeanProxy.lookupServiceReferencesByServiceInterfaceName(serviceInterfaceName);
+ public Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceQName) {
+ return configTransactionControllerMXBeanProxy.lookupServiceReferencesByServiceInterfaceName(serviceInterfaceQName);
}
@Override
return configTransactionControllerMXBeanProxy.removeServiceReferences(objectName);
}
+ @Override
+ public ObjectName getServiceReference(String serviceInterfaceQName, String refName) throws InstanceNotFoundException {
+ return configTransactionControllerMXBeanProxy.getServiceReference(serviceInterfaceQName, refName);
+ }
+
+ @Override
+ public void checkServiceReferenceExists(ObjectName objectName) throws InstanceNotFoundException {
+ configTransactionControllerMXBeanProxy.checkServiceReferenceExists(objectName);
+ }
+
@Override
public void validateBean(ObjectName configBeanON)
throws ValidationException {
}
@Override
- public ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceName, String refName) {
+ public ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceQName, String refName) {
throw new UnsupportedOperationException();
}
}
@Override
- public Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName) {
+ public Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceQName) {
throw new UnsupportedOperationException();
}
public Set<String> getAvailableModuleFactoryQNames() {
throw new UnsupportedOperationException();
}
+
+ @Override
+ public ObjectName getServiceReference(String serviceInterfaceQName, String refName) throws InstanceNotFoundException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void checkServiceReferenceExists(ObjectName objectName) throws InstanceNotFoundException {
+ throw new UnsupportedOperationException();
+ }
}
}
@Override
- public void saveServiceReference(String serviceInterfaceName, String refName, ObjectName objectName) throws InstanceNotFoundException {
+ public ObjectName saveServiceReference(String serviceInterfaceName, String refName, ObjectName moduleON) throws InstanceNotFoundException {
throw new UnsupportedOperationException();
}
@Override
- public boolean removeServiceReference(String serviceInterfaceName, String refName) {
+ public void removeServiceReference(String serviceInterfaceName, String refName) {
throw new UnsupportedOperationException();
}
}
@Override
- public ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceName, String refName) {
+ public ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceQName, String refName) {
throw new UnsupportedOperationException();
}
}
@Override
- public Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName) {
+ public Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceQName) {
throw new UnsupportedOperationException();
}
public Set<String> getAvailableModuleFactoryQNames() {
throw new UnsupportedOperationException();
}
+
+ @Override
+ public ObjectName getServiceReference(String serviceInterfaceQName, String refName) throws InstanceNotFoundException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void checkServiceReferenceExists(ObjectName objectName) throws InstanceNotFoundException {
+ throw new UnsupportedOperationException();
+ }
}
}
<#list moduleFields as field>
<#if field.dependent==true>
- if (${field.name}Dependency == null) {
- if (other.${field.name}Dependency != null)
- return false;
- } else if (!${field.name}Dependency.equals(other.${field.name}Dependency)) {
+ if (${field.name}Dependency != other.${field.name}Dependency) { // reference to dependency must be same
return false;
}
<#else>