/**
* 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>