* Provides functionality for working with configuration registry - mainly
* creating and committing config transactions.
*/
-public interface ConfigRegistry extends LookupRegistry {
+public interface ConfigRegistry extends LookupRegistry, ServiceReferenceReadableRegistry {
/**
* Only well-known ObjectName in configuration system, under which
/**
* Represents functionality provided by configuration transaction.
*/
-public interface ConfigTransactionController extends LookupRegistry {
+public interface ConfigTransactionController extends LookupRegistry, ServiceReferenceReadableRegistry, ServiceReferenceWritableRegistry {
/**
* Create new configuration bean.
*/
String getTransactionName();
+ /**
+ * @return all known module factory names as reported by {@link org.opendaylight.controller.config.spi.ModuleFactory#getImplementationName()}
+ */
Set<String> getAvailableModuleNames();
}
*/
package org.opendaylight.controller.config.api;
-import java.util.Set;
-
import javax.management.InstanceNotFoundException;
import javax.management.ObjectName;
+import java.util.Set;
public interface LookupRegistry {
ObjectName lookupConfigBean(String moduleName, String instanceName)
throws InstanceNotFoundException;
+ /**
+ * Check that object name corresponds with existing module.
+ *
+ * @throws InstanceNotFoundException
+ * if search did not find exactly one instance
+ */
+ void checkConfigBeanExists(ObjectName objectName) throws InstanceNotFoundException;
+
}
--- /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.api;
+
+import javax.management.InstanceNotFoundException;
+import javax.management.ObjectName;
+import java.util.Map;
+import java.util.Set;
+
+public interface ServiceReferenceReadableRegistry {
+
+ /**
+ * Lookup object name by fully qualified service interface name and service reference name.
+ * @param serviceInterfaceName 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);
+
+ /**
+ * Get mapping of services to reference names and module object names.
+ */
+ Map<String /* serviceInterfaceName */, 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
+ * @throws IllegalArgumentException if there is a mismatch between serviceInterfaceName and objectName
+ */
+ Map<String /* refName */, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName);
+
+ /**
+ * Find all available service interface names of a module.
+ * @param objectName module object name
+ * @throws InstanceNotFoundException if search did not find exactly one instance
+ */
+ Set<String> lookupServiceInterfaceNames(ObjectName objectName) throws InstanceNotFoundException;
+
+ /**
+ * @param namespace service interface namespace
+ * @param localName service interface local name
+ * @return fully qualified name needed by all other service reference mapping methods.
+ * @throws java.lang.IllegalArgumentException if namespace or localName is not found
+ */
+ String getServiceInterfaceName(String namespace, String localName);
+
+}
--- /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.api;
+
+import javax.management.InstanceNotFoundException;
+import javax.management.ObjectName;
+
+public interface ServiceReferenceWritableRegistry extends ServiceReferenceReadableRegistry {
+ /**
+ * Create or update reference name to objectName. Reference name is unique per service interface 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;
+
+ /**
+ * 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);
+
+ /**
+ * Remove all service references.
+ */
+ void removeAllServiceReferences();
+
+ /**
+ * Remove all service references attached to given module.
+ * @return true iif at least one reference was removed
+ */
+ boolean removeServiceReferences(ObjectName objectName) throws InstanceNotFoundException;
+}
public @interface ServiceInterfaceAnnotation {
/**
- * Specifies human readable name of this service. Each service name should
- * be globally unique. Should not contain spaces.
+ * Fully qualified name of a service that must be globally unique.
+ * When generating service interfaces from yang, this will be QName of
+ * identity extending service-type.
*/
String value();
* is called.
*/
Class<?> osgiRegistrationType();
+
+ /**
+ * Get namespace of {@link #value()}
+ */
+ String namespace();
+
+ /**
+ * Get revision of {@link #value()}
+ */
+ String revision();
+
+ /**
+ * Get local name of {@link #value()}
+ */
+ String localName();
}
*/
package org.opendaylight.controller.config.api.jmx;
+import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.opendaylight.controller.config.api.jmx.constants.ConfigRegistryConstants;
+
+import javax.annotation.concurrent.ThreadSafe;
+import javax.management.ObjectName;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map.Entry;
import java.util.Set;
-import javax.annotation.concurrent.ThreadSafe;
-import javax.management.ObjectName;
-
-import org.opendaylight.controller.config.api.ModuleIdentifier;
-import org.opendaylight.controller.config.api.jmx.constants.ConfigRegistryConstants;
-
/**
* Provides ObjectName creation. Each created ObjectName consists of domain that
* is defined as {@link #ON_DOMAIN} and at least one key-value pair. The only
return objectName.getKeyProperty(TRANSACTION_NAME_KEY);
}
- public static ObjectName withoutTransactionName(ObjectName on) {
- if (getTransactionName(on) == null) {
+ /**
+ * Sanitize on: keep only mandatory attributes of module + metadata.
+ */
+ public static ObjectName withoutTransactionName(ObjectName inputON) {
+ if (getTransactionName(inputON) == null) {
throw new IllegalArgumentException(
- "Expected ObjectName with transaction:" + on);
+ "Expected ObjectName with transaction:" + inputON);
}
- if (ON_DOMAIN.equals(on.getDomain()) == false) {
+ if (ON_DOMAIN.equals(inputON.getDomain()) == false) {
throw new IllegalArgumentException("Expected different domain: "
- + on);
+ + inputON);
+ }
+ String moduleName = getFactoryName(inputON);
+ String instanceName = getInstanceName(inputON);
+
+
+ Map<String, String> allProperties = getAdditionalProperties(inputON);
+ Map<String, String> outputProperties = new HashMap<>(createModuleON(moduleName, instanceName));
+
+ for(Entry<String, String> entry: allProperties.entrySet()) {
+ if (entry.getKey().startsWith("X-")) {
+ outputProperties.put(entry.getKey(), entry.getValue());
+ }
}
- String moduleName = getFactoryName(on);
- String instanceName = getInstanceName(on);
- return createReadOnlyModuleON(moduleName, instanceName);
+ return createON(ON_DOMAIN, outputProperties);
}
private static void assertDoesNotContain(
boolean isModuleImplementingServiceInterface(
Class<? extends AbstractServiceInterface> serviceInterface);
+ Set<Class<? extends AbstractServiceInterface>> getImplementedServiceIntefaces();
+
/**
* Called when ModuleFactory is registered to config manager.
* Useful for populating the registry with pre-existing state. Since
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;
import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
@GuardedBy("this")
private List<ModuleFactory> lastListOfFactories = Collections.emptyList();
+ @GuardedBy("this") // switched in every 2ndPC
+ private ServiceReferenceReadableRegistry readableSRRegistry = ServiceReferenceRegistryImpl.createInitialSRLookupRegistry();
+
// constructor
public ConfigRegistryImpl(ModuleFactoriesResolver resolver,
BundleContext bundleContext, MBeanServer configMBeanServer) {
private synchronized ConfigTransactionControllerInternal beginConfigInternal(boolean blankTransaction) {
versionCounter++;
- String transactionName = "ConfigTransaction-" + version + "-" + versionCounter;
- TransactionJMXRegistrator transactionRegistrator = baseJMXRegistrator
- .createTransactionJMXRegistrator(transactionName);
- Map<String, Map.Entry<ModuleFactory, BundleContext>> allCurrentFactories = Collections.unmodifiableMap(resolver.getAllFactories());
+ final String transactionName = "ConfigTransaction-" + version + "-" + versionCounter;
+
+ TransactionJMXRegistratorFactory factory = new TransactionJMXRegistratorFactory() {
+ @Override
+ public TransactionJMXRegistrator create() {
+ return baseJMXRegistrator.createTransactionJMXRegistrator(transactionName);
+ }
+ };
+
+ ConfigTransactionLookupRegistry txLookupRegistry = new ConfigTransactionLookupRegistry(new TransactionIdentifier(
+ transactionName), factory);
+ Map<String, Map.Entry<ModuleFactory, BundleContext>> allCurrentFactories = Collections.unmodifiableMap(
+ resolver.getAllFactories());
+ ServiceReferenceWritableRegistry writableRegistry = ServiceReferenceRegistryImpl.createSRWritableRegistry(
+ readableSRRegistry, txLookupRegistry, allCurrentFactories);
+
ConfigTransactionControllerInternal transactionController = new ConfigTransactionControllerImpl(
- transactionName, transactionRegistrator, version,
- versionCounter, allCurrentFactories, transactionsMBeanServer, configMBeanServer, blankTransaction);
+ txLookupRegistry, version,
+ versionCounter, allCurrentFactories, transactionsMBeanServer,
+ configMBeanServer, blankTransaction, writableRegistry);
try {
- transactionRegistrator.registerMBean(transactionController, transactionController.getControllerObjectName());
+ txLookupRegistry.registerMBean(transactionController, transactionController.getControllerObjectName());
} catch (InstanceAlreadyExistsException e) {
throw new IllegalStateException(e);
}
-
transactionController.copyExistingModulesAndProcessFactoryDiff(currentConfig.getEntries(), lastListOfFactories);
-
transactionsHolder.add(transactionName, transactionController);
return transactionController;
}
// update version
version = configTransactionController.getVersion();
+
+ // switch readable Service Reference Registry
+ this.readableSRRegistry = ServiceReferenceRegistryImpl.createSRReadableRegistry(configTransactionController.getWritableRegistry(), this);
+
return new CommitStatus(newInstances, reusedInstances,
recreatedInstances);
}
return baseJMXRegistrator.queryNames(namePattern, null);
}
+ @Override
+ public void checkConfigBeanExists(ObjectName objectName) throws InstanceNotFoundException {
+ ObjectNameUtil.checkDomain(objectName);
+ ObjectNameUtil.checkType(objectName, ObjectNameUtil.TYPE_MODULE);
+ String transactionName = ObjectNameUtil.getTransactionName(objectName);
+ if (transactionName != null) {
+ throw new IllegalArgumentException("Transaction attribute not supported in registry, wrong ObjectName: " + objectName);
+ }
+ // make sure exactly one match is found:
+ LookupBeansUtil.lookupConfigBean(this, ObjectNameUtil.getFactoryName(objectName), ObjectNameUtil.getInstanceName(objectName));
+ }
+
+ // service reference functionality:
+ @Override
+ public synchronized ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceName, String refName) {
+ return readableSRRegistry.lookupConfigBeanByServiceInterfaceName(serviceInterfaceName, refName);
+ }
+
+ @Override
+ public synchronized Map<String, Map<String, ObjectName>> getServiceMapping() {
+ return readableSRRegistry.getServiceMapping();
+ }
+
+ @Override
+ public synchronized Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName) {
+ return readableSRRegistry.lookupServiceReferencesByServiceInterfaceName(serviceInterfaceName);
+ }
+
+ @Override
+ public synchronized Set<String> lookupServiceInterfaceNames(ObjectName objectName) throws InstanceNotFoundException {
+ return readableSRRegistry.lookupServiceInterfaceNames(objectName);
+ }
+
+ @Override
+ public synchronized String getServiceInterfaceName(String namespace, String localName) {
+ return readableSRRegistry.getServiceInterfaceName(namespace, localName);
+ }
}
/**
import org.opendaylight.controller.config.api.DependencyResolver;
import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.opendaylight.controller.config.api.ServiceReferenceWritableRegistry;
import org.opendaylight.controller.config.api.ValidationException;
import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
import org.opendaylight.controller.config.manager.impl.dependencyresolver.DependencyResolverManager;
import org.opendaylight.controller.config.manager.impl.dynamicmbean.ReadOnlyAtomicBoolean;
import org.opendaylight.controller.config.manager.impl.dynamicmbean.ReadOnlyAtomicBoolean.ReadOnlyAtomicBooleanImpl;
import org.opendaylight.controller.config.manager.impl.factoriesresolver.HierarchicalConfigMBeanFactoriesHolder;
-import org.opendaylight.controller.config.manager.impl.jmx.TransactionJMXRegistrator;
import org.opendaylight.controller.config.manager.impl.jmx.TransactionModuleJMXRegistrator;
import org.opendaylight.controller.config.manager.impl.jmx.TransactionModuleJMXRegistrator.TransactionModuleJMXRegistration;
-import org.opendaylight.controller.config.manager.impl.util.LookupBeansUtil;
import org.opendaylight.controller.config.spi.Module;
import org.opendaylight.controller.config.spi.ModuleFactory;
import org.opendaylight.yangtools.concepts.Identifiable;
/**
* This is a JMX bean representing current transaction. It contains
- * {@link #transactionIdentifier}, unique version and parent version for
+ * transaction identifier, unique version and parent version for
* optimistic locking.
*/
class ConfigTransactionControllerImpl implements
Identifiable<TransactionIdentifier>{
private static final Logger logger = LoggerFactory.getLogger(ConfigTransactionControllerImpl.class);
- private final TransactionIdentifier transactionIdentifier;
+ private final ConfigTransactionLookupRegistry txLookupRegistry;
private final ObjectName controllerON;
- private final TransactionJMXRegistrator transactionRegistrator;
- private final TransactionModuleJMXRegistrator txModuleJMXRegistrator;
+
private final long parentVersion, currentVersion;
private final HierarchicalConfigMBeanFactoriesHolder factoriesHolder;
private final DependencyResolverManager dependencyResolverManager;
private final boolean blankTransaction;
- public ConfigTransactionControllerImpl(String transactionName,
- TransactionJMXRegistrator transactionRegistrator,
+ @GuardedBy("this")
+ private final ServiceReferenceWritableRegistry writableSRRegistry;
+
+ public ConfigTransactionControllerImpl(ConfigTransactionLookupRegistry txLookupRegistry,
long parentVersion, long currentVersion,
Map<String, Map.Entry<ModuleFactory, BundleContext>> currentlyRegisteredFactories,
MBeanServer transactionsMBeanServer, MBeanServer configMBeanServer,
- boolean blankTransaction) {
-
- this.transactionIdentifier = new TransactionIdentifier(transactionName);
- this.controllerON = ObjectNameUtil
- .createTransactionControllerON(transactionName);
- this.transactionRegistrator = transactionRegistrator;
- txModuleJMXRegistrator = transactionRegistrator
- .createTransactionModuleJMXRegistrator();
+ boolean blankTransaction, ServiceReferenceWritableRegistry writableSRRegistry) {
+
+ this.txLookupRegistry = txLookupRegistry;
+ String transactionName = txLookupRegistry.getTransactionIdentifier().getName();
+ this.controllerON = ObjectNameUtil.createTransactionControllerON(transactionName);
this.parentVersion = parentVersion;
this.currentVersion = currentVersion;
this.currentlyRegisteredFactories = currentlyRegisteredFactories;
this.transactionsMBeanServer = transactionsMBeanServer;
this.configMBeanServer = configMBeanServer;
this.blankTransaction = blankTransaction;
+ this.writableSRRegistry = writableSRRegistry;
}
@Override
+ moduleIdentifier + ", got " + dependencyResolver.getIdentifier());
}
DynamicMBean writableDynamicWrapper = new DynamicWritableWrapper(
- module, moduleIdentifier, transactionIdentifier,
+ module, moduleIdentifier, getTransactionIdentifier(),
readOnlyAtomicBoolean, transactionsMBeanServer,
configMBeanServer);
ObjectName writableON = ObjectNameUtil.createTransactionModuleON(
- transactionIdentifier.getName(), moduleIdentifier);
+ getTransactionIdentifier().getName(), moduleIdentifier);
// put wrapper to jmx
- TransactionModuleJMXRegistration transactionModuleJMXRegistration = txModuleJMXRegistrator
+ TransactionModuleJMXRegistration transactionModuleJMXRegistration = getTxModuleJMXRegistrator()
.registerMBean(writableDynamicWrapper, writableON);
ModuleInternalTransactionalInfo moduleInternalTransactionalInfo = new ModuleInternalTransactionalInfo(
moduleIdentifier, module, moduleFactory,
}
@Override
- public synchronized void destroyModule(ObjectName objectName)
- throws InstanceNotFoundException {
+ public synchronized void destroyModule(ObjectName objectName) throws InstanceNotFoundException {
+ checkTransactionName(objectName);
+ ObjectNameUtil.checkDomain(objectName);
+ ModuleIdentifier moduleIdentifier = ObjectNameUtil.fromON(objectName,
+ ObjectNameUtil.TYPE_MODULE);
+ destroyModule(moduleIdentifier);
+ }
+
+ private void checkTransactionName(ObjectName objectName) {
String foundTransactionName = ObjectNameUtil
.getTransactionName(objectName);
- if (transactionIdentifier.getName().equals(foundTransactionName) == false) {
+ if (getTransactionIdentifier().getName().equals(foundTransactionName) == false) {
throw new IllegalArgumentException("Wrong transaction name "
+ objectName);
}
- ObjectNameUtil.checkDomain(objectName);
- ModuleIdentifier moduleIdentifier = ObjectNameUtil.fromON(objectName,
- ObjectNameUtil.TYPE_MODULE);
- destroyModule(moduleIdentifier);
}
private synchronized void destroyModule(ModuleIdentifier moduleIdentifier) {
logger.warn("Warning: removing default bean. This will be forbidden in next version of config-subsystem");
}
}
+ // first remove refNames, it checks for objectname existence
+ try {
+ writableSRRegistry.removeServiceReferences(
+ ObjectNameUtil.createTransactionModuleON(getTransactionName(),moduleIdentifier));
+ } catch (InstanceNotFoundException e) {
+ logger.error("Possible code error: cannot find {} in {}", moduleIdentifier, writableSRRegistry);
+ throw new IllegalStateException("Possible code error: cannot find " + moduleIdentifier, e);
+ }
+
ModuleInternalTransactionalInfo removedTInfo = dependencyResolverManager.destroyModule(moduleIdentifier);
// remove from jmx
removedTInfo.getTransactionModuleJMXRegistration().close();
private void validate_noLocks() throws ValidationException {
transactionStatus.checkNotAborted();
- logger.info("Validating transaction {}", transactionIdentifier);
+ logger.info("Validating transaction {}", getTransactionIdentifier());
// call validate()
List<ValidationException> collectedExceptions = new ArrayList<>();
for (Entry<ModuleIdentifier, Module> entry : dependencyResolverManager
throw ValidationException
.createFromCollectedValidationExceptions(collectedExceptions);
}
- logger.info("Validated transaction {}", transactionIdentifier);
+ logger.info("Validated transaction {}", getTransactionIdentifier());
}
/**
+ "to obtain a lock");
}
- logger.info("Committing transaction {}", transactionIdentifier);
+ logger.info("Committing transaction {}", getTransactionIdentifier());
// call getInstance()
for (Entry<ModuleIdentifier, Module> entry : dependencyResolverManager
ModuleIdentifier name = entry.getKey();
try {
logger.debug("About to commit {} in transaction {}",
- name, transactionIdentifier);
+ name, getTransactionIdentifier());
module.getInstance();
} catch (Exception e) {
logger.error("Commit failed on {} in transaction {}", name,
- transactionIdentifier, e);
+ getTransactionIdentifier(), e);
internalAbort();
throw new RuntimeException(
format("Error - getInstance() failed for %s in transaction %s",
- name, transactionIdentifier), e);
+ name, getTransactionIdentifier()), e);
}
}
// count dependency order
- logger.info("Committed configuration {}", transactionIdentifier);
+ logger.info("Committed configuration {}", getTransactionIdentifier());
transactionStatus.setCommitted();
// unregister this and all modules from jmx
close();
}
private void close() {
- transactionRegistrator.close();
+ //FIXME: should not close object that was retrieved in constructor, a wrapper object should do that perhaps
+ txLookupRegistry.close();
}
@Override
@Override
public String getTransactionName() {
- return transactionIdentifier.getName();
+ return getTransactionIdentifier().getName();
}
/**
*/
@Override
public Set<ObjectName> lookupConfigBeans() {
- return lookupConfigBeans("*", "*");
+ return txLookupRegistry.lookupConfigBeans();
}
/**
*/
@Override
public Set<ObjectName> lookupConfigBeans(String moduleName) {
- return lookupConfigBeans(moduleName, "*");
+ return txLookupRegistry.lookupConfigBeans(moduleName);
}
/**
@Override
public ObjectName lookupConfigBean(String moduleName, String instanceName)
throws InstanceNotFoundException {
- return LookupBeansUtil.lookupConfigBean(this, moduleName, instanceName);
+ return txLookupRegistry.lookupConfigBean(moduleName, instanceName);
}
/**
* {@inheritDoc}
*/
@Override
- public Set<ObjectName> lookupConfigBeans(String moduleName,
- String instanceName) {
- ObjectName namePattern = ObjectNameUtil.createModulePattern(moduleName,
- instanceName, transactionIdentifier.getName());
- return txModuleJMXRegistrator.queryNames(namePattern, null);
+ public Set<ObjectName> lookupConfigBeans(String moduleName, String instanceName) {
+ return txLookupRegistry.lookupConfigBeans(moduleName, instanceName);
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void checkConfigBeanExists(ObjectName objectName) throws InstanceNotFoundException {
+ txLookupRegistry.checkConfigBeanExists(objectName);
+ }
+ // --
+
+ /**
+ * {@inheritDoc}
+ */
@Override
public Set<String> getAvailableModuleNames() {
return factoriesHolder.getModuleNames();
// @VisibleForTesting
TransactionModuleJMXRegistrator getTxModuleJMXRegistrator() {
- return txModuleJMXRegistrator;
+ return txLookupRegistry.getTxModuleJMXRegistrator();
}
public TransactionIdentifier getName() {
- return transactionIdentifier;
+ return getTransactionIdentifier();
}
@Override
@Override
public TransactionIdentifier getIdentifier() {
- return transactionIdentifier;
+ return getTransactionIdentifier();
}
@Override
}
return factoryBundleContextEntry.getValue();
}
+
+ // service reference functionality:
+
+
+ @Override
+ public synchronized ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceName, String refName) {
+ return writableSRRegistry.lookupConfigBeanByServiceInterfaceName(serviceInterfaceName, refName);
+ }
+
+ @Override
+ public synchronized Map<String, Map<String, ObjectName>> getServiceMapping() {
+ return writableSRRegistry.getServiceMapping();
+ }
+
+ @Override
+ public synchronized Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName) {
+ return writableSRRegistry.lookupServiceReferencesByServiceInterfaceName(serviceInterfaceName);
+ }
+
+ @Override
+ public synchronized Set<String> lookupServiceInterfaceNames(ObjectName objectName) throws InstanceNotFoundException {
+ return writableSRRegistry.lookupServiceInterfaceNames(objectName);
+ }
+
+ @Override
+ public synchronized String getServiceInterfaceName(String namespace, String localName) {
+ return writableSRRegistry.getServiceInterfaceName(namespace, localName);
+ }
+
+ @Override
+ public synchronized void saveServiceReference(String serviceInterfaceName, String refName, ObjectName objectName) throws InstanceNotFoundException {
+ writableSRRegistry.saveServiceReference(serviceInterfaceName, refName, objectName);
+ }
+
+ @Override
+ public synchronized boolean removeServiceReference(String serviceInterfaceName, String refName) {
+ return writableSRRegistry.removeServiceReference(serviceInterfaceName, refName);
+ }
+
+ @Override
+ public synchronized void removeAllServiceReferences() {
+ writableSRRegistry.removeAllServiceReferences();
+ }
+
+ @Override
+ public boolean removeServiceReferences(ObjectName objectName) throws InstanceNotFoundException {
+ return writableSRRegistry.removeServiceReferences(objectName);
+ }
+
+ @Override
+ public ServiceReferenceWritableRegistry getWritableRegistry() {
+ return writableSRRegistry;
+ }
+
+ public TransactionIdentifier getTransactionIdentifier() {
+ return txLookupRegistry.getTransactionIdentifier();
+ }
+
}
import javax.management.ObjectName;
import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.opendaylight.controller.config.api.ServiceReferenceWritableRegistry;
import org.opendaylight.controller.config.api.ValidationException;
import org.opendaylight.controller.config.spi.ModuleFactory;
import org.osgi.framework.BundleContext;
List<ModuleFactory> getCurrentlyRegisteredFactories();
BundleContext getModuleFactoryBundleContext(String factoryName);
+
+ ServiceReferenceWritableRegistry getWritableRegistry();
+
}
--- /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.LookupRegistry;
+import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
+import org.opendaylight.controller.config.manager.impl.jmx.TransactionJMXRegistrator;
+import org.opendaylight.controller.config.manager.impl.jmx.TransactionModuleJMXRegistrator;
+import org.opendaylight.controller.config.manager.impl.util.LookupBeansUtil;
+
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.InstanceNotFoundException;
+import javax.management.ObjectName;
+import java.io.Closeable;
+import java.util.Set;
+
+/**
+ * Responsible for creating TransactionJMXRegistrator, registering transaction and all its beans,
+ * lookup of beans, closing of TransactionJMXRegistrator.
+ */
+class ConfigTransactionLookupRegistry implements LookupRegistry, Closeable {
+ private final TransactionJMXRegistrator transactionJMXRegistrator;
+ private final TransactionIdentifier transactionIdentifier;
+ private final TransactionModuleJMXRegistrator txModuleJMXRegistrator;
+
+ ConfigTransactionLookupRegistry(TransactionIdentifier transactionIdentifier,
+ TransactionJMXRegistratorFactory factory) {
+ this.transactionIdentifier = transactionIdentifier;
+ this.transactionJMXRegistrator = factory.create();
+ this.txModuleJMXRegistrator = transactionJMXRegistrator.createTransactionModuleJMXRegistrator();
+ }
+
+ private void checkTransactionName(ObjectName objectName) {
+ String foundTransactionName = ObjectNameUtil
+ .getTransactionName(objectName);
+ if (transactionIdentifier.getName().equals(foundTransactionName) == false) {
+ throw new IllegalArgumentException("Wrong transaction name "
+ + objectName);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Set<ObjectName> lookupConfigBeans() {
+ return lookupConfigBeans("*", "*");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Set<ObjectName> lookupConfigBeans(String moduleName) {
+ return lookupConfigBeans(moduleName, "*");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public ObjectName lookupConfigBean(String moduleName, String instanceName)
+ throws InstanceNotFoundException {
+ return LookupBeansUtil.lookupConfigBean(this, moduleName, instanceName);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Set<ObjectName> lookupConfigBeans(String moduleName,
+ String instanceName) {
+ ObjectName namePattern = ObjectNameUtil.createModulePattern(moduleName,
+ instanceName, transactionIdentifier.getName());
+ return txModuleJMXRegistrator.queryNames(namePattern, null);
+ }
+
+ @Override
+ public void checkConfigBeanExists(ObjectName objectName) throws InstanceNotFoundException {
+ ObjectNameUtil.checkDomain(objectName);
+ ObjectNameUtil.checkType(objectName, ObjectNameUtil.TYPE_MODULE);
+ checkTransactionName(objectName);
+ // make sure exactly one match is found:
+ LookupBeansUtil.lookupConfigBean(this, ObjectNameUtil.getFactoryName(objectName), ObjectNameUtil.getInstanceName(objectName));
+ }
+
+ TransactionIdentifier getTransactionIdentifier() {
+ return transactionIdentifier;
+ }
+
+ TransactionModuleJMXRegistrator getTxModuleJMXRegistrator() {
+ return txModuleJMXRegistrator;
+ }
+
+ public void close() {
+ transactionJMXRegistrator.close();
+ }
+
+ public void registerMBean(ConfigTransactionControllerInternal transactionController, ObjectName controllerObjectName) throws InstanceAlreadyExistsException {
+ transactionJMXRegistrator.registerMBean(transactionController, controllerObjectName);
+ }
+}
+
+interface TransactionJMXRegistratorFactory {
+ TransactionJMXRegistrator create();
+}
--- /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.LookupRegistry;
+import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
+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.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.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 {
+ 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;
+ // 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;
+
+ /**
+ * Static constructor for config registry. Since only transaction can write to this registry, it will
+ * return blank state.
+ */
+ public static ServiceReferenceReadableRegistry createInitialSRLookupRegistry() {
+ // since this is initial state, just throw exception:
+ LookupRegistry lookupRegistry = new LookupRegistry() {
+ @Override
+ public Set<ObjectName> lookupConfigBeans() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Set<ObjectName> lookupConfigBeans(String moduleName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Set<ObjectName> lookupConfigBeans(String moduleName, String instanceName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public ObjectName lookupConfigBean(String moduleName, String instanceName) throws InstanceNotFoundException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void checkConfigBeanExists(ObjectName objectName) throws InstanceNotFoundException {
+ throw new InstanceNotFoundException("Cannot find " + objectName);
+ }
+ };
+ return new ServiceReferenceRegistryImpl(Collections.<String, ModuleFactory>emptyMap(), lookupRegistry,
+ Collections.<String /* qName */, Map<String /* refName */, ModuleIdentifier>>emptyMap());
+ }
+
+ /**
+ * 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) {
+
+ ServiceReferenceRegistryImpl old = (ServiceReferenceRegistryImpl) oldReadableRegistry;
+ Map<String, ModuleFactory> factories = extractFactoriesMap(currentlyRegisteredFactories);
+ return new ServiceReferenceRegistryImpl(factories, lookupRegistry, Collections.unmodifiableMap(old.refNames));
+ }
+
+ /**
+ * Copy back state to config registry after commit.
+ */
+ public static ServiceReferenceReadableRegistry createSRReadableRegistry(ServiceReferenceWritableRegistry oldWritableRegistry, LookupRegistry lookupRegistry) {
+ 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));
+ }
+
+ private static Map<String, ModuleFactory> extractFactoriesMap(Map<String, Map.Entry<ModuleFactory, BundleContext>> currentlyRegisteredFactories) {
+ Map<String, ModuleFactory> result = new HashMap<>();
+ for (Entry<String, Entry<ModuleFactory, BundleContext>> entry : currentlyRegisteredFactories.entrySet()) {
+ result.put(entry.getKey(), entry.getValue().getKey());
+ }
+ return result;
+ }
+
+ private ServiceReferenceRegistryImpl(Map<String, ModuleFactory> factories, LookupRegistry lookupRegistry,
+ Map<String /* qName */, Map<String /* refName */, ModuleIdentifier>> refNamesToCopy) {
+ this.factories = factories;
+ this.lookupRegistry = lookupRegistry;
+ Map<String, Set<String /* QName */>> factoryNamesToQNames = new HashMap<>();
+ Set<ServiceInterfaceAnnotation> allAnnotations = new HashSet<>();
+ Set<String /* qName */> allQNames = new HashSet<>();
+ for (Entry<String, ModuleFactory> entry : factories.entrySet()) {
+ if (entry.getKey().equals(entry.getValue().getImplementationName()) == false) {
+ logger.error("Possible error in code: Mismatch between supplied and actual name of {}", entry);
+ throw new IllegalArgumentException("Possible error in code: Mismatch between supplied and actual name of " + entry);
+ }
+ Set<ServiceInterfaceAnnotation> siAnnotations = InterfacesHelper.getServiceInterfaceAnnotations(entry.getValue());
+ Set<String> qNames = new HashSet<>();
+ for (ServiceInterfaceAnnotation sia: siAnnotations) {
+ qNames.add(sia.value());
+ }
+ allAnnotations.addAll(siAnnotations);
+ allQNames.addAll(qNames);
+ factoryNamesToQNames.put(entry.getKey(), Collections.unmodifiableSet(qNames));
+ }
+ this.factoryNamesToQNames = Collections.unmodifiableMap(factoryNamesToQNames);
+ this.allQNames = Collections.unmodifiableSet(allQNames);
+ // fill namespacesToAnnotations
+ Map<String /* namespace */, Map<String /* localName */, ServiceInterfaceAnnotation>> namespacesToAnnotations =
+ new HashMap<>();
+ for (ServiceInterfaceAnnotation sia : allAnnotations) {
+ Map<String, ServiceInterfaceAnnotation> ofNamespace = namespacesToAnnotations.get(sia.namespace());
+ if (ofNamespace == null) {
+ ofNamespace = new HashMap<>();
+ namespacesToAnnotations.put(sia.namespace(), ofNamespace);
+ }
+ if (ofNamespace.containsKey(sia.localName())) {
+ logger.error("Cannot construct namespacesToAnnotations map, conflict between local names in {}, offending local name: {}, map so far {}",
+ sia.namespace(), sia.localName(), namespacesToAnnotations);
+ throw new IllegalArgumentException("Conflict between local names in " + sia.namespace() + " : " + sia.localName());
+ }
+ ofNamespace.put(sia.localName(), sia);
+ }
+ 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 {
+ lookupRegistry.checkConfigBeanExists(objectName);
+
+ String factoryName = ObjectNameUtil.getFactoryName(objectName);
+ Set<String> serviceInterfaceAnnotations = factoryNamesToQNames.get(factoryName);
+ if (serviceInterfaceAnnotations == null) {
+ logger.error("Possible error in code: cannot find factory annotations of '{}' extracted from ON {} in {}",
+ factoryName, objectName, factoryNamesToQNames);
+ throw new IllegalArgumentException("Cannot find factory with name " + factoryName);
+ }
+ return serviceInterfaceAnnotations;
+ }
+
+ @Override
+ public 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);
+ throw new IllegalArgumentException("Cannot find namespace " + namespace);
+ }
+ ServiceInterfaceAnnotation sia = ofNamespace.get(localName);
+ if (sia == null) {
+ logger.error("Cannot find local name {} in namespace {}, found only {}", localName, namespace, ofNamespace);
+ throw new IllegalArgumentException("Cannot find local name " + localName + " in namespace " + namespace);
+ }
+ return sia.value();
+ }
+
+
+
+ // reading:
+
+ @Override
+ public 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);
+ }
+ }
+ return result;
+ }
+
+ private ObjectName getObjectName(ModuleIdentifier moduleIdentifier) {
+ ObjectName on;
+ try {
+ on = lookupRegistry.lookupConfigBean(moduleIdentifier.getFactoryName(), moduleIdentifier.getInstanceName());
+ } catch (InstanceNotFoundException e) {
+ logger.error("Cannot find instance {}", moduleIdentifier);
+ throw new IllegalStateException("Cannot find instance " + moduleIdentifier, e);
+ }
+ return on;
+ }
+
+ @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);
+ 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);
+ }
+ return getObjectName(moduleIdentifier);
+ }
+
+ @Override
+ public Map<String /* refName */, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName) {
+ Map<String, ModuleIdentifier> innerMap = refNames.get(serviceInterfaceName);
+ if (innerMap == null) {
+ logger.error("Cannot find qname {} in {}", serviceInterfaceName, refNames);
+ throw new IllegalArgumentException("Cannot find " + serviceInterfaceName);
+ }
+ 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 result;
+ }
+
+ // writing:
+
+ @Override
+ public void saveServiceReference(String serviceInterfaceName, String refName, ObjectName objectName) throws InstanceNotFoundException {
+ // make sure it is found
+ lookupRegistry.checkConfigBeanExists(objectName);
+ String factoryName = ObjectNameUtil.getFactoryName(objectName);
+ // 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);
+ throw new IllegalStateException("Possible error in code: cannot find annotations of existing factory " + factoryName);
+ }
+ // 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 );
+ }
+ 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);
+ }
+ 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);
+ }
+ Map<String, ModuleIdentifier> ofQName = refNames.get(serviceInterfaceName);
+ if (ofQName == null) {
+ return false;
+ }
+ return ofQName.remove(refName) != null;
+ }
+
+ @Override
+ public void removeAllServiceReferences() {
+ refNames.clear();
+ }
+
+ @Override
+ public boolean removeServiceReferences(ObjectName objectName) throws InstanceNotFoundException {
+ lookupRegistry.checkConfigBeanExists(objectName);
+ String factoryName = ObjectNameUtil.getFactoryName(objectName);
+ // 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);
+ throw new IllegalStateException("Possible error in code: cannot find annotations of existing factory " + factoryName);
+ }
+ String instanceName = ObjectNameUtil.getInstanceName(objectName);
+ 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();
+ }
+ }
+ }
+ }
+ return found;
+ }
+
+ @Override
+ public String toString() {
+ return "ServiceReferenceRegistryImpl{" +
+ "refNames=" + refNames +
+ ", factoryNamesToQNames=" + factoryNamesToQNames +
+ '}';
+ }
+}
}
@Override
- public void close() {
+ public void close() { // closes also all child TransactionModuleJMXRegistrator instances
childJMXRegistrator.close();
}
}
*/
package org.opendaylight.controller.config.manager.impl.util;
+import org.opendaylight.controller.config.api.annotations.AbstractServiceInterface;
+import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation;
+import org.opendaylight.controller.config.spi.Module;
+import org.opendaylight.controller.config.spi.ModuleFactory;
+
+import javax.management.JMX;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
-import javax.management.JMX;
-
-import org.opendaylight.controller.config.api.annotations.AbstractServiceInterface;
-import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation;
-import org.opendaylight.controller.config.spi.Module;
-
public class InterfacesHelper {
public static Set<Class<?>> getAllInterfaces(Class<?> clazz) {
// get parent class
clazz = clazz.getSuperclass();
}
+ return getAllSuperInterfaces(toBeInspected);
+
+ }
+
+ private static Set<Class<?>> getAllSuperInterfaces(Set<Class<?>> ifcs) {
+ ifcs = new HashSet<>(ifcs); // create copy to modify
// each interface can extend other interfaces
- Set<Class<?>> inspected = new HashSet<>();
- while (toBeInspected.size() > 0) {
- Iterator<Class<?>> iterator = toBeInspected.iterator();
+ Set<Class<?>> result = new HashSet<>();
+ while (ifcs.size() > 0) {
+ Iterator<Class<?>> iterator = ifcs.iterator();
Class<?> ifc = iterator.next();
iterator.remove();
- toBeInspected.addAll(Arrays.asList(ifc.getInterfaces()));
- inspected.add(ifc);
+ if (ifc.isInterface() == false) {
+ throw new IllegalArgumentException(ifc + " should be an interface");
+ }
+ ifcs.addAll(Arrays.asList(ifc.getInterfaces()));
+ result.add(ifc);
}
- return inspected;
+ return result;
}
/**
return result;
}
+ public static Set<Class<? extends AbstractServiceInterface>> getAllAbstractServiceClasses(Class<? extends Module> configBeanClass) {
+
+ Set<Class<? extends AbstractServiceInterface>> foundGeneratedSIClasses = new HashSet<>();
+ for (Class<?> clazz : getAllInterfaces(configBeanClass)) {
+ if (AbstractServiceInterface.class.isAssignableFrom(clazz) && AbstractServiceInterface.class.equals(clazz) == false) {
+ foundGeneratedSIClasses.add((Class<? extends AbstractServiceInterface>) clazz);
+ }
+ }
+ return getAllAbstractServiceInterfaceClasses(foundGeneratedSIClasses);
+ }
+
+
/**
* Get OSGi registration types under which config bean instance should be
* registered. This is specified in
return result;
}
+
+ public static Set<ServiceInterfaceAnnotation> getServiceInterfaceAnnotations(ModuleFactory factory) {
+ Set<Class<? extends AbstractServiceInterface>> implementedServiceIntefaces = Collections.unmodifiableSet(factory.getImplementedServiceIntefaces());
+ return getServiceInterfaceAnnotations(implementedServiceIntefaces);
+ }
+
+ private static Set<ServiceInterfaceAnnotation> getServiceInterfaceAnnotations(Set<Class<? extends AbstractServiceInterface>> implementedServiceIntefaces) {
+ Set<Class<? extends AbstractServiceInterface>> inspected = getAllAbstractServiceInterfaceClasses(implementedServiceIntefaces);
+ Set<ServiceInterfaceAnnotation> result = new HashSet<>();
+ // SIs can form hierarchies, inspect superclass until it does not extend AbstractSI
+ for (Class<?> clazz : inspected) {
+ ServiceInterfaceAnnotation annotation = clazz.getAnnotation(ServiceInterfaceAnnotation.class);
+ if (annotation != null) {
+ result.add(annotation);
+ }
+ }
+ return result;
+ }
+
+ static Set<Class<? extends AbstractServiceInterface>> getAllAbstractServiceInterfaceClasses(
+ Set<Class<? extends AbstractServiceInterface>> directlyImplementedAbstractSIs) {
+
+ Set<Class<?>> allInterfaces = getAllSuperInterfaces((Set) directlyImplementedAbstractSIs);
+ Set<Class<? extends AbstractServiceInterface>> result = new HashSet<>();
+ for(Class<?> ifc: allInterfaces){
+ if (AbstractServiceInterface.class.isAssignableFrom(ifc) &&
+ ifc.equals(AbstractServiceInterface.class) == false) {
+ result.add((Class<? extends AbstractServiceInterface>) ifc);
+ }
+
+ }
+ return result;
+ }
}
import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
import org.opendaylight.controller.config.api.ModuleIdentifier;
import org.opendaylight.controller.config.api.annotations.AbstractServiceInterface;
+import org.opendaylight.controller.config.manager.impl.util.InterfacesHelper;
import org.opendaylight.controller.config.spi.Module;
import org.opendaylight.controller.config.spi.ModuleFactory;
import org.osgi.framework.BundleContext;
public Set<Module> getDefaultModules(DependencyResolverFactory dependencyResolverFactory, BundleContext bundleContext) {
return new HashSet<Module>();
}
+
+ @Override
+ public Set<Class<? extends AbstractServiceInterface>> getImplementedServiceIntefaces() {
+ return InterfacesHelper.getAllAbstractServiceClasses(configBeanClass);
+ }
}
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import org.opendaylight.controller.config.api.ServiceReferenceWritableRegistry;
import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
import org.opendaylight.controller.config.manager.impl.jmx.BaseJMXRegistrator;
import org.opendaylight.controller.config.manager.impl.jmx.TransactionJMXRegistrator;
ManagementFactory.getPlatformMBeanServer());
transactionsMBeanServer = MBeanServerFactory.createMBeanServer();
Map<String, Map.Entry<ModuleFactory, BundleContext>> currentlyRegisteredFactories = new HashMap<>();
- TransactionJMXRegistrator jmxRegistrator123 = baseJMXRegistrator
- .createTransactionJMXRegistrator(transactionName123);
+
+ ConfigTransactionLookupRegistry txLookupRegistry = new ConfigTransactionLookupRegistry(new TransactionIdentifier(transactionName123), new TransactionJMXRegistratorFactory() {
+ @Override
+ public TransactionJMXRegistrator create() {
+ return baseJMXRegistrator.createTransactionJMXRegistrator(transactionName123);
+ }
+ });
+
+ ServiceReferenceWritableRegistry writableRegistry = ServiceReferenceRegistryImpl.createSRWritableRegistry(
+ ServiceReferenceRegistryImpl.createInitialSRLookupRegistry(), txLookupRegistry, currentlyRegisteredFactories);
+
testedTxController = new ConfigTransactionControllerImpl(
- transactionName123, jmxRegistrator123, 1, 1,
+ txLookupRegistry, 1, 1,
currentlyRegisteredFactories, transactionsMBeanServer,
- ManagementFactory.getPlatformMBeanServer(), false);
+ ManagementFactory.getPlatformMBeanServer(), false, writableRegistry);
TransactionModuleJMXRegistrator transactionModuleJMXRegistrator123 = testedTxController
.getTxModuleJMXRegistrator();
transactionModuleJMXRegistrator123.registerMBean(
static final String SIMPLE = "simple";
static final String SUBCLASS2 = "subclass2";
- @ServiceInterfaceAnnotation(value = SIMPLE, osgiRegistrationType = Executor.class)
+ @ServiceInterfaceAnnotation(value = SIMPLE, osgiRegistrationType = Executor.class,
+ namespace = "ns", revision = "rev", localName = SIMPLE)
static interface SimpleSI extends AbstractServiceInterface {
}
}
- @ServiceInterfaceAnnotation(value = SUBCLASS2, osgiRegistrationType = ExecutorService.class)
+ @ServiceInterfaceAnnotation(value = SUBCLASS2, osgiRegistrationType = ExecutorService.class,
+ namespace = "ns", revision = "rev", localName = SUBCLASS2)
+
static interface SubSI2 extends SubSI {
}
import static org.junit.Assert.assertEquals;
+import java.util.HashSet;
import java.util.Set;
import javax.management.MXBean;
import org.junit.Test;
+import org.opendaylight.controller.config.api.annotations.AbstractServiceInterface;
+import org.opendaylight.controller.config.manager.testingservices.seviceinterface.TestingScheduledThreadPoolServiceInterface;
+import org.opendaylight.controller.config.manager.testingservices.seviceinterface.TestingThreadPoolServiceInterface;
import org.opendaylight.controller.config.spi.Module;
import org.opendaylight.yangtools.concepts.Identifiable;
assertEquals(expected, InterfacesHelper.getMXInterfaces(SubClass.class));
}
+ @Test
+ public void testGetAllAbstractServiceInterfaceClasses(){
+ Class<? extends AbstractServiceInterface> clazz = TestingScheduledThreadPoolServiceInterface.class;
+ Set<Class<? extends AbstractServiceInterface>> input = new HashSet<>();
+ input.add(clazz);
+ Set<Class<? extends AbstractServiceInterface>> result = InterfacesHelper.getAllAbstractServiceInterfaceClasses(input);
+
+ Set<Class<?>> expected = Sets.newHashSet((Class<?>) TestingScheduledThreadPoolServiceInterface.class,
+ TestingThreadPoolServiceInterface.class
+ );
+ assertEquals(expected, result);
+ }
+
}
import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation;
-@ServiceInterfaceAnnotation(value = TestingParallelAPSPConfigMXBean.NAME, osgiRegistrationType = TestingAPSP.class)
+@ServiceInterfaceAnnotation(value = TestingParallelAPSPConfigMXBean.NAME, osgiRegistrationType = TestingAPSP.class,
+namespace = "namespace", revision = "rev", localName = TestingParallelAPSPConfigMXBean.NAME)
public interface TestingParallelAPSPConfigMXBean {
static final String NAME = "apsp";
import javax.annotation.concurrent.ThreadSafe;
import javax.management.ObjectName;
+import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
public Set<Module> getDefaultModules(DependencyResolverFactory dependencyResolverFactory, BundleContext context) {
return new HashSet<Module>();
}
+
+ @Override
+ public Set<Class<? extends AbstractServiceInterface>> getImplementedServiceIntefaces() {
+ return Collections.emptySet();
+ }
}
*/
package org.opendaylight.controller.config.manager.testingservices.scheduledthreadpool;
+import com.google.common.collect.Sets;
import org.opendaylight.controller.config.api.DependencyResolver;
import org.opendaylight.controller.config.api.DependencyResolverFactory;
import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
import org.opendaylight.controller.config.spi.ModuleFactory;
import org.osgi.framework.BundleContext;
-import java.util.Arrays;
+import java.util.Collections;
import java.util.HashSet;
-import java.util.List;
import java.util.Set;
public class TestingScheduledThreadPoolModuleFactory implements ModuleFactory {
public static final String NAME = "scheduled";
- private static List<Class<? extends TestingThreadPoolServiceInterface>> ifc = Arrays
- .asList(TestingScheduledThreadPoolServiceInterface.class, TestingThreadPoolServiceInterface.class);
+ private static Set<Class<? extends AbstractServiceInterface>> ifc = Collections.unmodifiableSet(Sets.newHashSet(
+ (Class<? extends AbstractServiceInterface>) TestingScheduledThreadPoolServiceInterface.class,
+ TestingThreadPoolServiceInterface.class));
@Override
public boolean isModuleImplementingServiceInterface(
public Set<Module> getDefaultModules(DependencyResolverFactory dependencyResolverFactory, BundleContext bundleContext) {
return new HashSet<Module>();
}
+
+ @Override
+ public Set<Class<? extends AbstractServiceInterface>> getImplementedServiceIntefaces() {
+ return ifc;
+ }
+
+
}
import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation;
import org.opendaylight.controller.config.manager.testingservices.threadpool.TestingModifiableThreadPoolIfc;
-@ServiceInterfaceAnnotation(value = "modifiable-threadpool", osgiRegistrationType = TestingModifiableThreadPoolIfc.class)
+@ServiceInterfaceAnnotation(value = "fqn:modifiable-threadpool", osgiRegistrationType = TestingModifiableThreadPoolIfc.class,
+ namespace = "foo", revision = "bar", localName = "modifiable-threadpool")
public interface ModifiableThreadPoolServiceInterface extends
TestingThreadPoolServiceInterface {
}
import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation;
import org.opendaylight.controller.config.manager.testingservices.scheduledthreadpool.TestingScheduledThreadPoolIfc;
-@ServiceInterfaceAnnotation(value = "threadpool-scheduled", osgiRegistrationType = TestingScheduledThreadPoolIfc.class)
+@ServiceInterfaceAnnotation(value = "threadpool-scheduled", osgiRegistrationType = TestingScheduledThreadPoolIfc.class,
+ namespace = "ns", revision = "rev", localName = "threadpool-scheduled")
public interface TestingScheduledThreadPoolServiceInterface extends
TestingThreadPoolServiceInterface {
}
import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation;
import org.opendaylight.controller.config.manager.testingservices.threadpool.TestingThreadPoolIfc;
-@ServiceInterfaceAnnotation(value = "testing-threadpool", osgiRegistrationType = TestingThreadPoolIfc.class)
+@ServiceInterfaceAnnotation(value = "testing-threadpool", osgiRegistrationType = TestingThreadPoolIfc.class,
+ namespace = "ns", revision = "foo", localName = "bar")
public interface TestingThreadPoolServiceInterface extends
AbstractServiceInterface {
}
*/
package org.opendaylight.controller.config.manager.testingservices.threadpool;
+import com.google.common.collect.Sets;
import org.opendaylight.controller.config.api.DependencyResolver;
import org.opendaylight.controller.config.api.DependencyResolverFactory;
import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
import org.opendaylight.controller.config.spi.ModuleFactory;
import org.osgi.framework.BundleContext;
-import java.util.Arrays;
+import java.util.Collections;
import java.util.HashSet;
-import java.util.List;
import java.util.Set;
public class TestingFixedThreadPoolModuleFactory implements ModuleFactory {
public static final String NAME = "fixed";
- private static List<Class<? extends TestingThreadPoolServiceInterface>> ifc = Arrays
- .asList(ModifiableThreadPoolServiceInterface.class, TestingThreadPoolServiceInterface.class);
+
+ private static Set<Class<? extends AbstractServiceInterface>> ifc = Collections.unmodifiableSet(Sets.newHashSet(
+ (Class<? extends AbstractServiceInterface>) ModifiableThreadPoolServiceInterface.class,
+ TestingThreadPoolServiceInterface.class));
@Override
public String getImplementationName() {
public Set<Module> getDefaultModules(DependencyResolverFactory dependencyResolverFactory, BundleContext bundleContext) {
return new HashSet<Module>();
}
+
+ @Override
+ public Set<Class<? extends AbstractServiceInterface>> getImplementedServiceIntefaces() {
+ return ifc;
+ }
}
import java.util.Arrays;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import javax.management.AttributeNotFoundException;
import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
public class ConfigRegistryJMXClient implements ConfigRegistryClient {
- private final ConfigRegistryMXBean configRegistryProxy;
+ private final ConfigRegistryMXBean configRegistryMXBeanProxy;
private final ObjectName configRegistryON;
private final MBeanServer configMBeanServer;
if (!(searchResult.size() == 1)) {
throw new IllegalStateException("Config registry not found");
}
- configRegistryProxy = JMX.newMXBeanProxy(configMBeanServer, configRegistryON, ConfigRegistryMXBean.class,
+ configRegistryMXBeanProxy = JMX.newMXBeanProxy(configMBeanServer, configRegistryON, ConfigRegistryMXBean.class,
false);
}
@Override
public ConfigTransactionJMXClient getConfigTransactionClient(
ObjectName objectName) {
- return new ConfigTransactionJMXClient(configRegistryProxy, objectName,
+ return new ConfigTransactionJMXClient(configRegistryMXBeanProxy, objectName,
configMBeanServer);
}
@Override
public ObjectName beginConfig() {
- return configRegistryProxy.beginConfig();
+ return configRegistryMXBeanProxy.beginConfig();
}
@Override
public CommitStatus commitConfig(ObjectName transactionControllerON)
throws ConflictingVersionException, ValidationException {
- return configRegistryProxy.commitConfig(transactionControllerON);
+ return configRegistryMXBeanProxy.commitConfig(transactionControllerON);
}
@Override
public List<ObjectName> getOpenConfigs() {
- return configRegistryProxy.getOpenConfigs();
+ return configRegistryMXBeanProxy.getOpenConfigs();
}
@Override
@Override
public Set<String> getAvailableModuleNames() {
- return configRegistryProxy.getAvailableModuleNames();
+ return configRegistryMXBeanProxy.getAvailableModuleNames();
}
@Override
public boolean isHealthy() {
- return configRegistryProxy.isHealthy();
+ return configRegistryMXBeanProxy.isHealthy();
}
@Override
public Set<ObjectName> lookupConfigBeans() {
- return configRegistryProxy.lookupConfigBeans();
+ return configRegistryMXBeanProxy.lookupConfigBeans();
}
@Override
public Set<ObjectName> lookupConfigBeans(String moduleName) {
- return configRegistryProxy.lookupConfigBeans(moduleName);
+ return configRegistryMXBeanProxy.lookupConfigBeans(moduleName);
}
@Override
public Set<ObjectName> lookupConfigBeans(String moduleName,
String instanceName) {
- return configRegistryProxy.lookupConfigBeans(moduleName, instanceName);
+ return configRegistryMXBeanProxy.lookupConfigBeans(moduleName, instanceName);
}
@Override
public ObjectName lookupConfigBean(String moduleName, String instanceName)
throws InstanceNotFoundException {
- return configRegistryProxy.lookupConfigBean(moduleName, instanceName);
+ return configRegistryMXBeanProxy.lookupConfigBean(moduleName, instanceName);
}
@Override
public Set<ObjectName> lookupRuntimeBeans() {
- return configRegistryProxy.lookupRuntimeBeans();
+ return configRegistryMXBeanProxy.lookupRuntimeBeans();
}
@Override
public Set<ObjectName> lookupRuntimeBeans(String ifcName,
String instanceName) {
- return configRegistryProxy.lookupRuntimeBeans(ifcName, instanceName);
+ return configRegistryMXBeanProxy.lookupRuntimeBeans(ifcName, instanceName);
+ }
+
+ @Override
+ public void checkConfigBeanExists(ObjectName objectName) throws InstanceNotFoundException {
+ configRegistryMXBeanProxy.checkConfigBeanExists(objectName);
+ }
+
+ @Override
+ public ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceName, String refName) {
+ return configRegistryMXBeanProxy.lookupConfigBeanByServiceInterfaceName(serviceInterfaceName, refName);
+ }
+
+ @Override
+ public Map<String, Map<String, ObjectName>> getServiceMapping() {
+ return configRegistryMXBeanProxy.getServiceMapping();
+ }
+
+ @Override
+ public Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName) {
+ return configRegistryMXBeanProxy.lookupServiceReferencesByServiceInterfaceName(serviceInterfaceName);
+ }
+
+ @Override
+ public Set<String> lookupServiceInterfaceNames(ObjectName objectName) throws InstanceNotFoundException {
+ return configRegistryMXBeanProxy.lookupServiceInterfaceNames(objectName);
+ }
+
+ @Override
+ public String getServiceInterfaceName(String namespace, String localName) {
+ return configRegistryMXBeanProxy.getServiceInterfaceName(namespace, localName);
}
@Override
*/
package org.opendaylight.controller.config.util;
+import java.util.Map;
import java.util.Set;
import javax.management.Attribute;
import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
public class ConfigTransactionJMXClient implements ConfigTransactionClient {
- private final ConfigRegistryMXBean configTransactionManagerProxy;
+ private final ConfigRegistryMXBean configRegistryMXBeanProxy;
private final ObjectName configTransactionControllerON;
- private final ConfigTransactionControllerMXBean configControllerProxy;
+ private final ConfigTransactionControllerMXBean configTransactionControllerMXBeanProxy;
private final MBeanServer configMBeanServer;
public ConfigTransactionJMXClient(
- ConfigRegistryMXBean configTransactionManagerProxy,
+ ConfigRegistryMXBean configRegistryMXBeanProxy,
ObjectName configTransactionControllerON,
MBeanServer configMBeanServer) {
this.configMBeanServer = configMBeanServer;
- this.configTransactionManagerProxy = configTransactionManagerProxy;
+ this.configRegistryMXBeanProxy = configRegistryMXBeanProxy;
this.configTransactionControllerON = configTransactionControllerON;
- this.configControllerProxy = JMX.newMXBeanProxy(configMBeanServer,
+ this.configTransactionControllerMXBeanProxy = JMX.newMXBeanProxy(configMBeanServer,
configTransactionControllerON,
ConfigTransactionControllerMXBean.class);
}
@Override
public CommitStatus commit() throws ConflictingVersionException,
ValidationException {
- return configTransactionManagerProxy
+ return configRegistryMXBeanProxy
.commitConfig(configTransactionControllerON);
}
@Override
public ObjectName createModule(String moduleName, String instanceName)
throws InstanceAlreadyExistsException {
- return configControllerProxy.createModule(moduleName, instanceName);
+ return configTransactionControllerMXBeanProxy.createModule(moduleName, instanceName);
}
@Override
public void destroyModule(ObjectName objectName)
throws InstanceNotFoundException {
- configControllerProxy.destroyModule(objectName);
+ configTransactionControllerMXBeanProxy.destroyModule(objectName);
}
@Override
@Override
public void abortConfig() {
- configControllerProxy.abortConfig();
+ configTransactionControllerMXBeanProxy.abortConfig();
}
@Override
public void validateConfig() throws ValidationException {
- configControllerProxy.validateConfig();
+ configTransactionControllerMXBeanProxy.validateConfig();
}
@Override
@Override
public String getTransactionName() {
- return configControllerProxy.getTransactionName();
+ return configTransactionControllerMXBeanProxy.getTransactionName();
}
@Override
public Set<String> getAvailableModuleNames() {
- return configControllerProxy.getAvailableModuleNames();
+ return configTransactionControllerMXBeanProxy.getAvailableModuleNames();
}
@Override
@Override
public Set<ObjectName> lookupConfigBeans() {
- return configControllerProxy.lookupConfigBeans();
+ return configTransactionControllerMXBeanProxy.lookupConfigBeans();
}
@Override
public Set<ObjectName> lookupConfigBeans(String moduleName) {
- return configControllerProxy.lookupConfigBeans(moduleName);
+ return configTransactionControllerMXBeanProxy.lookupConfigBeans(moduleName);
}
@Override
public ObjectName lookupConfigBean(String moduleName, String instanceName)
throws InstanceNotFoundException {
- return configControllerProxy.lookupConfigBean(moduleName, instanceName);
+ return configTransactionControllerMXBeanProxy.lookupConfigBean(moduleName, instanceName);
}
@Override
public Set<ObjectName> lookupConfigBeans(String moduleName,
String instanceName) {
- return configControllerProxy
+ return configTransactionControllerMXBeanProxy
.lookupConfigBeans(moduleName, instanceName);
}
+ @Override
+ public void checkConfigBeanExists(ObjectName objectName) throws InstanceNotFoundException {
+ configTransactionControllerMXBeanProxy.checkConfigBeanExists(objectName);
+ }
+
+ @Override
+ public void saveServiceReference(String serviceInterfaceName, String refName, ObjectName objectName) throws InstanceNotFoundException {
+ configTransactionControllerMXBeanProxy.saveServiceReference(serviceInterfaceName,refName,objectName);
+ }
+
+ @Override
+ public boolean removeServiceReference(String serviceInterfaceName, String refName) {
+ return configTransactionControllerMXBeanProxy.removeServiceReference(serviceInterfaceName, refName);
+ }
+
+ @Override
+ public void removeAllServiceReferences() {
+ configTransactionControllerMXBeanProxy.removeAllServiceReferences();
+ }
+
+ @Override
+ public ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceName, String refName) {
+ return configTransactionControllerMXBeanProxy.lookupConfigBeanByServiceInterfaceName(serviceInterfaceName, refName);
+ }
+
+ @Override
+ public Map<String, Map<String, ObjectName>> getServiceMapping() {
+ return configTransactionControllerMXBeanProxy.getServiceMapping();
+ }
+
+ @Override
+ public Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName) {
+ return configTransactionControllerMXBeanProxy.lookupServiceReferencesByServiceInterfaceName(serviceInterfaceName);
+ }
+
+ @Override
+ public Set<String> lookupServiceInterfaceNames(ObjectName objectName) throws InstanceNotFoundException {
+ return configTransactionControllerMXBeanProxy.lookupServiceInterfaceNames(objectName);
+ }
+
+ @Override
+ public String getServiceInterfaceName(String namespace, String localName) {
+ return configTransactionControllerMXBeanProxy.getServiceInterfaceName(namespace, localName);
+ }
+
+ @Override
+ public boolean removeServiceReferences(ObjectName objectName) throws InstanceNotFoundException {
+ return configTransactionControllerMXBeanProxy.removeServiceReferences(objectName);
+ }
+
@Override
public void validateBean(ObjectName configBeanON)
throws ValidationException {
package org.opendaylight.controller.config.util.jolokia;
import java.util.List;
+import java.util.Map;
import java.util.Set;
+import javax.management.InstanceNotFoundException;
import javax.management.ObjectName;
import org.jolokia.client.request.J4pExecRequest;
import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
import org.opendaylight.controller.config.util.ConfigRegistryClient;
+@Deprecated
public class ConfigRegistryJolokiaClient extends ListableJolokiaClient
implements ConfigRegistryClient {
public Object getAttributeCurrentValue(ObjectName on, String attributeName) {
throw new UnsupportedOperationException();
}
+
+ // TODO: implement or deprecate
+ @Override
+ public void checkConfigBeanExists(ObjectName objectName) throws InstanceNotFoundException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceName, String refName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Map<String, Map<String, ObjectName>> getServiceMapping() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Set<String> lookupServiceInterfaceNames(ObjectName objectName) throws InstanceNotFoundException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getServiceInterfaceName(String namespace, String localName) {
+ throw new UnsupportedOperationException();
+ }
}
package org.opendaylight.controller.config.util.jolokia;
import java.util.Map;
+import java.util.Set;
import javax.management.Attribute;
import javax.management.AttributeNotFoundException;
import org.opendaylight.controller.config.util.AttributeEntry;
import org.opendaylight.controller.config.util.ConfigTransactionClient;
+@Deprecated
public class ConfigTransactionJolokiaClient extends ListableJolokiaClient
implements ConfigTransactionClient {
throw new UnsupportedOperationException();
}
+ // TODO: implement or deprecate
+ @Override
+ public void checkConfigBeanExists(ObjectName objectName) throws InstanceNotFoundException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void saveServiceReference(String serviceInterfaceName, String refName, ObjectName objectName) throws InstanceNotFoundException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean removeServiceReference(String serviceInterfaceName, String refName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void removeAllServiceReferences() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceName, String refName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Map<String, Map<String, ObjectName>> getServiceMapping() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Set<String> lookupServiceInterfaceNames(ObjectName objectName) throws InstanceNotFoundException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getServiceInterfaceName(String namespace, String localName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean removeServiceReferences(ObjectName objectName) throws InstanceNotFoundException {
+ throw new UnsupportedOperationException();
+ }
}
import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
import org.opendaylight.controller.config.util.AttributeEntry;
+
abstract class ListableJolokiaClient {
protected final J4pClient j4pClient;
protected final String url;
import java.lang.management.ManagementFactory;
import java.lang.reflect.Method;
+import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
ManagementFactory.getPlatformMBeanServer());
jolokiaTransactionClient = new ConfigTransactionJolokiaClient(
jolokiaURL, testingTransactionControllerON, null);
- lookupProvidersToClients = ImmutableMap
- .of(testingRegistry, Sets.newHashSet(jmxRegistryClient, jolokiaRegistryClient),
- testingTransactionController, Sets.newHashSet(jmxTransactionClient, jolokiaTransactionClient));
+ HashSet<ConfigRegistryClient> registryClients = Sets.newHashSet(jmxRegistryClient, jolokiaRegistryClient);
+ HashSet<ConfigTransactionClient> configTransactionClients = Sets.newHashSet(jmxTransactionClient, jolokiaTransactionClient);
+ lookupProvidersToClients = ImmutableMap.of((LookupRegistry) testingRegistry, registryClients, testingTransactionController, configTransactionClients);
}
@After
package org.opendaylight.controller.config.util;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import javax.management.InstanceNotFoundException;
}
}
+ @Override
+ public void checkConfigBeanExists(ObjectName objectName) throws InstanceNotFoundException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceName, String refName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Map<String, Map<String, ObjectName>> getServiceMapping() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Set<String> lookupServiceInterfaceNames(ObjectName objectName) throws InstanceNotFoundException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getServiceInterfaceName(String namespace, String localName) {
+ throw new UnsupportedOperationException();
+ }
}
*/
package org.opendaylight.controller.config.util;
+import java.util.Map;
import java.util.Set;
import javax.management.InstanceAlreadyExistsException;
return null;
}
}
+
+ @Override
+ public void checkConfigBeanExists(ObjectName objectName) throws InstanceNotFoundException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void saveServiceReference(String serviceInterfaceName, String refName, ObjectName objectName) throws InstanceNotFoundException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean removeServiceReference(String serviceInterfaceName, String refName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void removeAllServiceReferences() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceName, String refName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Map<String, Map<String, ObjectName>> getServiceMapping() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Set<String> lookupServiceInterfaceNames(ObjectName objectName) throws InstanceNotFoundException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getServiceInterfaceName(String namespace, String localName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean removeServiceReferences(ObjectName objectName) throws InstanceNotFoundException {
+ throw new UnsupportedOperationException();
+ }
}
Preconditions.checkNotNull(exportedClassName,
"Cannot create annotation from null exportedClassName");
- List<Parameter> params = Lists.newArrayList(new Parameter("value",
- q(qname.getLocalName())));
- params.add(new Parameter("osgiRegistrationType", exportedClassName
- + ".class"));
+ List<Parameter> params = Lists.newArrayList(new Parameter("value", q(qname.toString())));
+ params.add(new Parameter("osgiRegistrationType", exportedClassName + ".class"));
+
+ params.add(new Parameter("namespace", q(qname.getNamespace().toString())));
+ params.add(new Parameter("revision", q(qname.getFormattedRevision())));
+ params.add(new Parameter("localName", q(qname.getLocalName())));
+
return new Annotation(
ServiceInterfaceAnnotation.class.getCanonicalName(), params);
}
{
public static final java.lang.String NAME = "${globallyUniqueName}";
- private static final java.util.Set<Class<? extends ${abstractServiceInterfaceType}>> serviceIfcs = new java.util.HashSet<Class<? extends ${abstractServiceInterfaceType}>>();
+ private static final java.util.Set<Class<? extends ${abstractServiceInterfaceType}>> serviceIfcs;
<#if providedServices??>
static {
+ java.util.Set<Class<? extends ${abstractServiceInterfaceType}>> serviceIfcs2 = new java.util.HashSet<Class<? extends ${abstractServiceInterfaceType}>>();
<#list providedServices as refId>
- serviceIfcs.add(${refId});
+ serviceIfcs2.add(${refId});
</#list>
+ serviceIfcs = java.util.Collections.unmodifiableSet(serviceIfcs2);
}
</#if>
return false;
}
+ @Override
+ public java.util.Set<Class<? extends ${abstractServiceInterfaceType}>> getImplementedServiceIntefaces() {
+ return serviceIfcs;
+ }
+
+
@Override
public ${moduleType} createModule(String instanceName, ${dependencyResolverType} dependencyResolver, ${bundleContextType} bundleContext) {
return instantiateModule(instanceName, dependencyResolver, bundleContext);
"public static final java.lang.String NAME=\"threadfactory-naming\"");
assertDeclaredField(
fieldDeclarations,
- "private static final java.util.Set<Class<? extends org.opendaylight.controller.config.api.annotations.AbstractServiceInterface>> serviceIfcs=new java.util.HashSet<Class<? extends org.opendaylight.controller.config.api.annotations.AbstractServiceInterface>>()");
+ "private static final java.util.Set<Class<? extends org.opendaylight.controller.config.api.annotations.AbstractServiceInterface>> serviceIfcs");
assertEquals(2, fieldDeclarations.size());
- assertFactoryMethods(visitor.methods, 8);
+ assertFactoryMethods(visitor.methods, 9);
assertEquals("Incorrenct number of generated method descriptions", 0,
visitor.methodDescriptions.size());
assertEquals("Incorrenct number of generated method javadoc", 0,