From: Tomas Olvecky Date: Mon, 9 Dec 2013 12:20:56 +0000 (+0100) Subject: Add service reference binding to config registry. X-Git-Tag: jenkins-controller-bulk-release-prepare-only-2-1~212^2 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=0d36679800f7476120476ba371e62d16b17509f6 Add service reference binding to config registry. Add a database for persisting service references between commits. In netconf modules are wired together via link in /services/service xml subtree. Each service has an xpath pointer back to a /modules/module that implements the service. Consumer of a service then maintains a link to the service via its namespace and reference name. This commit fixes problem of reference names not surviving commits. Change-Id: I784f99617bb0072fc4dc3762a28e30f9b9bcf111 Signed-off-by: Tomas Olvecky --- diff --git a/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/ConfigRegistry.java b/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/ConfigRegistry.java index 5f23c90bbe..56b96e97bb 100644 --- a/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/ConfigRegistry.java +++ b/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/ConfigRegistry.java @@ -19,7 +19,7 @@ import org.opendaylight.controller.config.api.jmx.constants.ConfigRegistryConsta * 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 diff --git a/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/ConfigTransactionController.java b/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/ConfigTransactionController.java index 7e8ee64daa..c257e55dc0 100644 --- a/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/ConfigTransactionController.java +++ b/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/ConfigTransactionController.java @@ -16,7 +16,7 @@ import javax.management.ObjectName; /** * Represents functionality provided by configuration transaction. */ -public interface ConfigTransactionController extends LookupRegistry { +public interface ConfigTransactionController extends LookupRegistry, ServiceReferenceReadableRegistry, ServiceReferenceWritableRegistry { /** * Create new configuration bean. @@ -64,6 +64,9 @@ public interface ConfigTransactionController extends LookupRegistry { */ String getTransactionName(); + /** + * @return all known module factory names as reported by {@link org.opendaylight.controller.config.spi.ModuleFactory#getImplementationName()} + */ Set getAvailableModuleNames(); } diff --git a/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/LookupRegistry.java b/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/LookupRegistry.java index 7a3c4bf82d..8975471353 100644 --- a/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/LookupRegistry.java +++ b/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/LookupRegistry.java @@ -7,10 +7,9 @@ */ 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 { @@ -58,4 +57,12 @@ 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; + } diff --git a/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/ServiceReferenceReadableRegistry.java b/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/ServiceReferenceReadableRegistry.java new file mode 100644 index 0000000000..f84fcd48c9 --- /dev/null +++ b/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/ServiceReferenceReadableRegistry.java @@ -0,0 +1,53 @@ +/* + * 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> 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 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 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); + +} diff --git a/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/ServiceReferenceWritableRegistry.java b/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/ServiceReferenceWritableRegistry.java new file mode 100644 index 0000000000..f3d6d16d6c --- /dev/null +++ b/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/ServiceReferenceWritableRegistry.java @@ -0,0 +1,38 @@ +/* + * 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; +} diff --git a/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/annotations/ServiceInterfaceAnnotation.java b/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/annotations/ServiceInterfaceAnnotation.java index a81d992d81..e66de46520 100644 --- a/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/annotations/ServiceInterfaceAnnotation.java +++ b/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/annotations/ServiceInterfaceAnnotation.java @@ -23,8 +23,9 @@ import java.lang.annotation.Target; 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(); @@ -34,4 +35,19 @@ public @interface ServiceInterfaceAnnotation { * 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(); } diff --git a/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/jmx/ObjectNameUtil.java b/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/jmx/ObjectNameUtil.java index 8111690c72..cc1d89761c 100644 --- a/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/jmx/ObjectNameUtil.java +++ b/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/jmx/ObjectNameUtil.java @@ -7,6 +7,11 @@ */ 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; @@ -15,12 +20,6 @@ import java.util.Map; 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 @@ -129,18 +128,31 @@ public class ObjectNameUtil { 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 allProperties = getAdditionalProperties(inputON); + Map outputProperties = new HashMap<>(createModuleON(moduleName, instanceName)); + + for(Entry 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( diff --git a/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/spi/ModuleFactory.java b/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/spi/ModuleFactory.java index 7b8f7c164e..c86b381493 100644 --- a/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/spi/ModuleFactory.java +++ b/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/spi/ModuleFactory.java @@ -97,6 +97,8 @@ public interface ModuleFactory { boolean isModuleImplementingServiceInterface( Class serviceInterface); + Set> getImplementedServiceIntefaces(); + /** * Called when ModuleFactory is registered to config manager. * Useful for populating the registry with pre-existing state. Since diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigRegistryImpl.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigRegistryImpl.java index 1b695a9bda..18326d91f2 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigRegistryImpl.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigRegistryImpl.java @@ -10,6 +10,8 @@ package org.opendaylight.controller.config.manager.impl; 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; @@ -102,6 +104,9 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe @GuardedBy("this") private List lastListOfFactories = Collections.emptyList(); + @GuardedBy("this") // switched in every 2ndPC + private ServiceReferenceReadableRegistry readableSRRegistry = ServiceReferenceRegistryImpl.createInitialSRLookupRegistry(); + // constructor public ConfigRegistryImpl(ModuleFactoriesResolver resolver, BundleContext bundleContext, MBeanServer configMBeanServer) { @@ -142,21 +147,32 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe private synchronized ConfigTransactionControllerInternal beginConfigInternal(boolean blankTransaction) { versionCounter++; - String transactionName = "ConfigTransaction-" + version + "-" + versionCounter; - TransactionJMXRegistrator transactionRegistrator = baseJMXRegistrator - .createTransactionJMXRegistrator(transactionName); - Map> 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> 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; } @@ -352,6 +368,10 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe // update version version = configTransactionController.getVersion(); + + // switch readable Service Reference Registry + this.readableSRRegistry = ServiceReferenceRegistryImpl.createSRReadableRegistry(configTransactionController.getWritableRegistry(), this); + return new CommitStatus(newInstances, reusedInstances, recreatedInstances); } @@ -493,6 +513,43 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe 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> getServiceMapping() { + return readableSRRegistry.getServiceMapping(); + } + + @Override + public synchronized Map lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName) { + return readableSRRegistry.lookupServiceReferencesByServiceInterfaceName(serviceInterfaceName); + } + + @Override + public synchronized Set lookupServiceInterfaceNames(ObjectName objectName) throws InstanceNotFoundException { + return readableSRRegistry.lookupServiceInterfaceNames(objectName); + } + + @Override + public synchronized String getServiceInterfaceName(String namespace, String localName) { + return readableSRRegistry.getServiceInterfaceName(namespace, localName); + } } /** diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerImpl.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerImpl.java index 3e53a7a217..36485b1abf 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerImpl.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerImpl.java @@ -9,6 +9,7 @@ package org.opendaylight.controller.config.manager.impl; 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; @@ -16,10 +17,8 @@ import org.opendaylight.controller.config.manager.impl.dynamicmbean.DynamicWrita 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; @@ -47,7 +46,7 @@ import static java.lang.String.format; /** * 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 @@ -56,10 +55,9 @@ class ConfigTransactionControllerImpl implements Identifiable{ 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; @@ -80,19 +78,18 @@ class ConfigTransactionControllerImpl implements 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> 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; @@ -102,6 +99,7 @@ class ConfigTransactionControllerImpl implements this.transactionsMBeanServer = transactionsMBeanServer; this.configMBeanServer = configMBeanServer; this.blankTransaction = blankTransaction; + this.writableSRRegistry = writableSRRegistry; } @Override @@ -225,14 +223,14 @@ class ConfigTransactionControllerImpl implements + 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, @@ -243,18 +241,21 @@ class ConfigTransactionControllerImpl implements } @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) { @@ -268,6 +269,15 @@ class ConfigTransactionControllerImpl implements 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(); @@ -297,7 +307,7 @@ class ConfigTransactionControllerImpl implements private void validate_noLocks() throws ValidationException { transactionStatus.checkNotAborted(); - logger.info("Validating transaction {}", transactionIdentifier); + logger.info("Validating transaction {}", getTransactionIdentifier()); // call validate() List collectedExceptions = new ArrayList<>(); for (Entry entry : dependencyResolverManager @@ -317,7 +327,7 @@ class ConfigTransactionControllerImpl implements throw ValidationException .createFromCollectedValidationExceptions(collectedExceptions); } - logger.info("Validated transaction {}", transactionIdentifier); + logger.info("Validated transaction {}", getTransactionIdentifier()); } /** @@ -359,7 +369,7 @@ class ConfigTransactionControllerImpl implements + "to obtain a lock"); } - logger.info("Committing transaction {}", transactionIdentifier); + logger.info("Committing transaction {}", getTransactionIdentifier()); // call getInstance() for (Entry entry : dependencyResolverManager @@ -368,21 +378,21 @@ class ConfigTransactionControllerImpl implements 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(); @@ -403,7 +413,8 @@ class ConfigTransactionControllerImpl implements } 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 @@ -413,7 +424,7 @@ class ConfigTransactionControllerImpl implements @Override public String getTransactionName() { - return transactionIdentifier.getName(); + return getTransactionIdentifier().getName(); } /** @@ -421,7 +432,7 @@ class ConfigTransactionControllerImpl implements */ @Override public Set lookupConfigBeans() { - return lookupConfigBeans("*", "*"); + return txLookupRegistry.lookupConfigBeans(); } /** @@ -429,7 +440,7 @@ class ConfigTransactionControllerImpl implements */ @Override public Set lookupConfigBeans(String moduleName) { - return lookupConfigBeans(moduleName, "*"); + return txLookupRegistry.lookupConfigBeans(moduleName); } /** @@ -438,20 +449,29 @@ class ConfigTransactionControllerImpl implements @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 lookupConfigBeans(String moduleName, - String instanceName) { - ObjectName namePattern = ObjectNameUtil.createModulePattern(moduleName, - instanceName, transactionIdentifier.getName()); - return txModuleJMXRegistrator.queryNames(namePattern, null); + public Set 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 getAvailableModuleNames() { return factoriesHolder.getModuleNames(); @@ -473,11 +493,11 @@ class ConfigTransactionControllerImpl implements // @VisibleForTesting TransactionModuleJMXRegistrator getTxModuleJMXRegistrator() { - return txModuleJMXRegistrator; + return txLookupRegistry.getTxModuleJMXRegistrator(); } public TransactionIdentifier getName() { - return transactionIdentifier; + return getTransactionIdentifier(); } @Override @@ -487,7 +507,7 @@ class ConfigTransactionControllerImpl implements @Override public TransactionIdentifier getIdentifier() { - return transactionIdentifier; + return getTransactionIdentifier(); } @Override @@ -498,4 +518,62 @@ class ConfigTransactionControllerImpl implements } return factoryBundleContextEntry.getValue(); } + + // service reference functionality: + + + @Override + public synchronized ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceName, String refName) { + return writableSRRegistry.lookupConfigBeanByServiceInterfaceName(serviceInterfaceName, refName); + } + + @Override + public synchronized Map> getServiceMapping() { + return writableSRRegistry.getServiceMapping(); + } + + @Override + public synchronized Map lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName) { + return writableSRRegistry.lookupServiceReferencesByServiceInterfaceName(serviceInterfaceName); + } + + @Override + public synchronized Set 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(); + } + } diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerInternal.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerInternal.java index 4dc877c62b..82bae44a01 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerInternal.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerInternal.java @@ -13,6 +13,7 @@ import java.util.List; import javax.management.ObjectName; import org.opendaylight.controller.config.api.ModuleIdentifier; +import org.opendaylight.controller.config.api.ServiceReferenceWritableRegistry; import org.opendaylight.controller.config.api.ValidationException; import org.opendaylight.controller.config.spi.ModuleFactory; import org.osgi.framework.BundleContext; @@ -71,4 +72,7 @@ interface ConfigTransactionControllerInternal extends List getCurrentlyRegisteredFactories(); BundleContext getModuleFactoryBundleContext(String factoryName); + + ServiceReferenceWritableRegistry getWritableRegistry(); + } diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionLookupRegistry.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionLookupRegistry.java new file mode 100644 index 0000000000..5d1f0b3976 --- /dev/null +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionLookupRegistry.java @@ -0,0 +1,111 @@ +/* + * 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 lookupConfigBeans() { + return lookupConfigBeans("*", "*"); + } + + /** + * {@inheritDoc} + */ + @Override + public Set 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 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(); +} diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ServiceReferenceRegistryImpl.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ServiceReferenceRegistryImpl.java new file mode 100644 index 0000000000..2fd1ca6c2c --- /dev/null +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ServiceReferenceRegistryImpl.java @@ -0,0 +1,340 @@ +/* + * 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 factories; + private final Map> 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> namespacesToAnnotations; + // all Service Interface qNames for sanity checking + private final Set allQNames; + + // actual reference database + private final Map> 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 lookupConfigBeans() { + throw new UnsupportedOperationException(); + } + + @Override + public Set lookupConfigBeans(String moduleName) { + throw new UnsupportedOperationException(); + } + + @Override + public Set 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.emptyMap(), lookupRegistry, + Collections.>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> currentlyRegisteredFactories) { + + ServiceReferenceRegistryImpl old = (ServiceReferenceRegistryImpl) oldReadableRegistry; + Map 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 extractFactoriesMap(Map> currentlyRegisteredFactories) { + Map result = new HashMap<>(); + for (Entry> entry : currentlyRegisteredFactories.entrySet()) { + result.put(entry.getKey(), entry.getValue().getKey()); + } + return result; + } + + private ServiceReferenceRegistryImpl(Map factories, LookupRegistry lookupRegistry, + Map> refNamesToCopy) { + this.factories = factories; + this.lookupRegistry = lookupRegistry; + Map> factoryNamesToQNames = new HashMap<>(); + Set allAnnotations = new HashSet<>(); + Set allQNames = new HashSet<>(); + for (Entry 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 siAnnotations = InterfacesHelper.getServiceInterfaceAnnotations(entry.getValue()); + Set 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> namespacesToAnnotations = + new HashMap<>(); + for (ServiceInterfaceAnnotation sia : allAnnotations) { + Map 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> deepCopy = new HashMap<>(); + for (Entry> outerROEntry: refNamesToCopy.entrySet()) { + Map innerWritableMap = new HashMap<>(); + deepCopy.put(outerROEntry.getKey(), innerWritableMap); + for (Entry 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 lookupServiceInterfaceNames(ObjectName objectName) throws InstanceNotFoundException { + lookupRegistry.checkConfigBeanExists(objectName); + + String factoryName = ObjectNameUtil.getFactoryName(objectName); + Set 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 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> getServiceMapping() { + Map> result = new HashMap<>(); + for (Entry> outerEntry: refNames.entrySet()) { + String qName = outerEntry.getKey(); + Map innerMap = new HashMap<>(); + result.put(qName, innerMap); + for (Entry 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 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 lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName) { + Map innerMap = refNames.get(serviceInterfaceName); + if (innerMap == null) { + logger.error("Cannot find qname {} in {}", serviceInterfaceName, refNames); + throw new IllegalArgumentException("Cannot find " + serviceInterfaceName); + } + Map result = new HashMap<>(); + for (Entry 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 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 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 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 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 ofQName = refNames.get(qName); + if (ofQName != null) { + for(Iterator> it = ofQName.entrySet ().iterator(); it.hasNext();){ + Entry next = it.next(); + if (next.getValue().equals(moduleIdentifier)) { + found = true; + it.remove(); + } + } + } + } + return found; + } + + @Override + public String toString() { + return "ServiceReferenceRegistryImpl{" + + "refNames=" + refNames + + ", factoryNamesToQNames=" + factoryNamesToQNames + + '}'; + } +} diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/TransactionJMXRegistrator.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/TransactionJMXRegistrator.java index 523cbc5b01..b371c3f170 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/TransactionJMXRegistrator.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/TransactionJMXRegistrator.java @@ -65,7 +65,7 @@ public class TransactionJMXRegistrator implements Closeable { } @Override - public void close() { + public void close() { // closes also all child TransactionModuleJMXRegistrator instances childJMXRegistrator.close(); } } diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/util/InterfacesHelper.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/util/InterfacesHelper.java index 76cb64cf93..033f7222fc 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/util/InterfacesHelper.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/util/InterfacesHelper.java @@ -7,17 +7,18 @@ */ 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> getAllInterfaces(Class clazz) { @@ -32,16 +33,25 @@ public class InterfacesHelper { // get parent class clazz = clazz.getSuperclass(); } + return getAllSuperInterfaces(toBeInspected); + + } + + private static Set> getAllSuperInterfaces(Set> ifcs) { + ifcs = new HashSet<>(ifcs); // create copy to modify // each interface can extend other interfaces - Set> inspected = new HashSet<>(); - while (toBeInspected.size() > 0) { - Iterator> iterator = toBeInspected.iterator(); + Set> result = new HashSet<>(); + while (ifcs.size() > 0) { + Iterator> 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; } /** @@ -80,6 +90,18 @@ public class InterfacesHelper { return result; } + public static Set> getAllAbstractServiceClasses(Class configBeanClass) { + + Set> foundGeneratedSIClasses = new HashSet<>(); + for (Class clazz : getAllInterfaces(configBeanClass)) { + if (AbstractServiceInterface.class.isAssignableFrom(clazz) && AbstractServiceInterface.class.equals(clazz) == false) { + foundGeneratedSIClasses.add((Class) clazz); + } + } + return getAllAbstractServiceInterfaceClasses(foundGeneratedSIClasses); + } + + /** * Get OSGi registration types under which config bean instance should be * registered. This is specified in @@ -98,4 +120,37 @@ public class InterfacesHelper { return result; } + + public static Set getServiceInterfaceAnnotations(ModuleFactory factory) { + Set> implementedServiceIntefaces = Collections.unmodifiableSet(factory.getImplementedServiceIntefaces()); + return getServiceInterfaceAnnotations(implementedServiceIntefaces); + } + + private static Set getServiceInterfaceAnnotations(Set> implementedServiceIntefaces) { + Set> inspected = getAllAbstractServiceInterfaceClasses(implementedServiceIntefaces); + Set 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> getAllAbstractServiceInterfaceClasses( + Set> directlyImplementedAbstractSIs) { + + Set> allInterfaces = getAllSuperInterfaces((Set) directlyImplementedAbstractSIs); + Set> result = new HashSet<>(); + for(Class ifc: allInterfaces){ + if (AbstractServiceInterface.class.isAssignableFrom(ifc) && + ifc.equals(AbstractServiceInterface.class) == false) { + result.add((Class) ifc); + } + + } + return result; + } } diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/ClassBasedModuleFactory.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/ClassBasedModuleFactory.java index d23b5ca128..672f150914 100644 --- a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/ClassBasedModuleFactory.java +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/ClassBasedModuleFactory.java @@ -13,6 +13,7 @@ import org.opendaylight.controller.config.api.DependencyResolverFactory; 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; @@ -107,4 +108,9 @@ public class ClassBasedModuleFactory implements ModuleFactory { public Set getDefaultModules(DependencyResolverFactory dependencyResolverFactory, BundleContext bundleContext) { return new HashSet(); } + + @Override + public Set> getImplementedServiceIntefaces() { + return InterfacesHelper.getAllAbstractServiceClasses(configBeanClass); + } } diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerImplTest.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerImplTest.java index 22a959060c..43c75ef1e7 100644 --- a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerImplTest.java +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerImplTest.java @@ -11,6 +11,7 @@ import com.google.common.collect.Sets; 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; @@ -61,13 +62,22 @@ public class ConfigTransactionControllerImplTest extends ManagementFactory.getPlatformMBeanServer()); transactionsMBeanServer = MBeanServerFactory.createMBeanServer(); Map> 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( diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/dynamicmbean/AnnotationsTest.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/dynamicmbean/AnnotationsTest.java index cf6ed18c6c..75b0414711 100644 --- a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/dynamicmbean/AnnotationsTest.java +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/dynamicmbean/AnnotationsTest.java @@ -97,7 +97,8 @@ public class AnnotationsTest { 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 { } @@ -161,7 +162,9 @@ public class AnnotationsTest { } - @ServiceInterfaceAnnotation(value = SUBCLASS2, osgiRegistrationType = ExecutorService.class) + @ServiceInterfaceAnnotation(value = SUBCLASS2, osgiRegistrationType = ExecutorService.class, + namespace = "ns", revision = "rev", localName = SUBCLASS2) + static interface SubSI2 extends SubSI { } diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/util/InterfacesHelperTest.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/util/InterfacesHelperTest.java index 9a5452aa6c..22ea528030 100644 --- a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/util/InterfacesHelperTest.java +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/util/InterfacesHelperTest.java @@ -9,11 +9,15 @@ package org.opendaylight.controller.config.manager.impl.util; 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; @@ -60,4 +64,17 @@ public class InterfacesHelperTest { assertEquals(expected, InterfacesHelper.getMXInterfaces(SubClass.class)); } + @Test + public void testGetAllAbstractServiceInterfaceClasses(){ + Class clazz = TestingScheduledThreadPoolServiceInterface.class; + Set> input = new HashSet<>(); + input.add(clazz); + Set> result = InterfacesHelper.getAllAbstractServiceInterfaceClasses(input); + + Set> expected = Sets.newHashSet((Class) TestingScheduledThreadPoolServiceInterface.class, + TestingThreadPoolServiceInterface.class + ); + assertEquals(expected, result); + } + } diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/parallelapsp/TestingParallelAPSPConfigMXBean.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/parallelapsp/TestingParallelAPSPConfigMXBean.java index 4fd2f5f1b5..9674a110ce 100644 --- a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/parallelapsp/TestingParallelAPSPConfigMXBean.java +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/parallelapsp/TestingParallelAPSPConfigMXBean.java @@ -11,7 +11,8 @@ import javax.management.ObjectName; 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"; diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/parallelapsp/TestingParallelAPSPModuleFactory.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/parallelapsp/TestingParallelAPSPModuleFactory.java index 3adf11484e..50a58792e1 100644 --- a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/parallelapsp/TestingParallelAPSPModuleFactory.java +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/parallelapsp/TestingParallelAPSPModuleFactory.java @@ -18,6 +18,7 @@ import org.osgi.framework.BundleContext; import javax.annotation.concurrent.ThreadSafe; import javax.management.ObjectName; +import java.util.Collections; import java.util.HashSet; import java.util.Set; @@ -69,4 +70,9 @@ public class TestingParallelAPSPModuleFactory implements ModuleFactory { public Set getDefaultModules(DependencyResolverFactory dependencyResolverFactory, BundleContext context) { return new HashSet(); } + + @Override + public Set> getImplementedServiceIntefaces() { + return Collections.emptySet(); + } } diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/scheduledthreadpool/TestingScheduledThreadPoolModuleFactory.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/scheduledthreadpool/TestingScheduledThreadPoolModuleFactory.java index 2e1047849e..e5306a4fa6 100644 --- a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/scheduledthreadpool/TestingScheduledThreadPoolModuleFactory.java +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/scheduledthreadpool/TestingScheduledThreadPoolModuleFactory.java @@ -7,6 +7,7 @@ */ 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; @@ -18,16 +19,16 @@ import org.opendaylight.controller.config.spi.Module; 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> ifc = Arrays - .asList(TestingScheduledThreadPoolServiceInterface.class, TestingThreadPoolServiceInterface.class); + private static Set> ifc = Collections.unmodifiableSet(Sets.newHashSet( + (Class) TestingScheduledThreadPoolServiceInterface.class, + TestingThreadPoolServiceInterface.class)); @Override public boolean isModuleImplementingServiceInterface( @@ -70,4 +71,11 @@ public class TestingScheduledThreadPoolModuleFactory implements ModuleFactory { public Set getDefaultModules(DependencyResolverFactory dependencyResolverFactory, BundleContext bundleContext) { return new HashSet(); } + + @Override + public Set> getImplementedServiceIntefaces() { + return ifc; + } + + } diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/seviceinterface/ModifiableThreadPoolServiceInterface.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/seviceinterface/ModifiableThreadPoolServiceInterface.java index ab1b6bd218..5c30d1e977 100644 --- a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/seviceinterface/ModifiableThreadPoolServiceInterface.java +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/seviceinterface/ModifiableThreadPoolServiceInterface.java @@ -10,7 +10,8 @@ package org.opendaylight.controller.config.manager.testingservices.seviceinterfa 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 { } diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/seviceinterface/TestingScheduledThreadPoolServiceInterface.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/seviceinterface/TestingScheduledThreadPoolServiceInterface.java index e4e388c610..5ddc1892e3 100644 --- a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/seviceinterface/TestingScheduledThreadPoolServiceInterface.java +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/seviceinterface/TestingScheduledThreadPoolServiceInterface.java @@ -10,7 +10,8 @@ package org.opendaylight.controller.config.manager.testingservices.seviceinterfa 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 { } diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/seviceinterface/TestingThreadPoolServiceInterface.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/seviceinterface/TestingThreadPoolServiceInterface.java index fd5ab1780d..91a4cff415 100644 --- a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/seviceinterface/TestingThreadPoolServiceInterface.java +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/seviceinterface/TestingThreadPoolServiceInterface.java @@ -11,7 +11,8 @@ import org.opendaylight.controller.config.api.annotations.AbstractServiceInterfa 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 { } diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/threadpool/TestingFixedThreadPoolModuleFactory.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/threadpool/TestingFixedThreadPoolModuleFactory.java index cf05e44530..b749ea7511 100644 --- a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/threadpool/TestingFixedThreadPoolModuleFactory.java +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/threadpool/TestingFixedThreadPoolModuleFactory.java @@ -7,6 +7,7 @@ */ 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; @@ -18,15 +19,16 @@ import org.opendaylight.controller.config.spi.Module; 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> ifc = Arrays - .asList(ModifiableThreadPoolServiceInterface.class, TestingThreadPoolServiceInterface.class); + + private static Set> ifc = Collections.unmodifiableSet(Sets.newHashSet( + (Class) ModifiableThreadPoolServiceInterface.class, + TestingThreadPoolServiceInterface.class)); @Override public String getImplementationName() { @@ -71,4 +73,9 @@ public class TestingFixedThreadPoolModuleFactory implements ModuleFactory { public Set getDefaultModules(DependencyResolverFactory dependencyResolverFactory, BundleContext bundleContext) { return new HashSet(); } + + @Override + public Set> getImplementedServiceIntefaces() { + return ifc; + } } diff --git a/opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/ConfigRegistryJMXClient.java b/opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/ConfigRegistryJMXClient.java index 3a1efaeaaf..4ecc7c3a5c 100644 --- a/opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/ConfigRegistryJMXClient.java +++ b/opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/ConfigRegistryJMXClient.java @@ -9,6 +9,7 @@ package org.opendaylight.controller.config.util; import java.util.Arrays; import java.util.List; +import java.util.Map; import java.util.Set; import javax.management.AttributeNotFoundException; @@ -28,7 +29,7 @@ import org.opendaylight.controller.config.api.jmx.ConfigRegistryMXBean; 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; @@ -40,7 +41,7 @@ public class ConfigRegistryJMXClient implements ConfigRegistryClient { 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); } @@ -61,7 +62,7 @@ public class ConfigRegistryJMXClient implements ConfigRegistryClient { @Override public ConfigTransactionJMXClient getConfigTransactionClient( ObjectName objectName) { - return new ConfigTransactionJMXClient(configRegistryProxy, objectName, + return new ConfigTransactionJMXClient(configRegistryMXBeanProxy, objectName, configMBeanServer); } @@ -75,18 +76,18 @@ public class ConfigRegistryJMXClient implements ConfigRegistryClient { @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 getOpenConfigs() { - return configRegistryProxy.getOpenConfigs(); + return configRegistryMXBeanProxy.getOpenConfigs(); } @Override @@ -101,45 +102,75 @@ public class ConfigRegistryJMXClient implements ConfigRegistryClient { @Override public Set getAvailableModuleNames() { - return configRegistryProxy.getAvailableModuleNames(); + return configRegistryMXBeanProxy.getAvailableModuleNames(); } @Override public boolean isHealthy() { - return configRegistryProxy.isHealthy(); + return configRegistryMXBeanProxy.isHealthy(); } @Override public Set lookupConfigBeans() { - return configRegistryProxy.lookupConfigBeans(); + return configRegistryMXBeanProxy.lookupConfigBeans(); } @Override public Set lookupConfigBeans(String moduleName) { - return configRegistryProxy.lookupConfigBeans(moduleName); + return configRegistryMXBeanProxy.lookupConfigBeans(moduleName); } @Override public Set 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 lookupRuntimeBeans() { - return configRegistryProxy.lookupRuntimeBeans(); + return configRegistryMXBeanProxy.lookupRuntimeBeans(); } @Override public Set 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> getServiceMapping() { + return configRegistryMXBeanProxy.getServiceMapping(); + } + + @Override + public Map lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName) { + return configRegistryMXBeanProxy.lookupServiceReferencesByServiceInterfaceName(serviceInterfaceName); + } + + @Override + public Set lookupServiceInterfaceNames(ObjectName objectName) throws InstanceNotFoundException { + return configRegistryMXBeanProxy.lookupServiceInterfaceNames(objectName); + } + + @Override + public String getServiceInterfaceName(String namespace, String localName) { + return configRegistryMXBeanProxy.getServiceInterfaceName(namespace, localName); } @Override diff --git a/opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/ConfigTransactionJMXClient.java b/opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/ConfigTransactionJMXClient.java index 548c0e9ea4..bd6f6fa884 100644 --- a/opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/ConfigTransactionJMXClient.java +++ b/opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/ConfigTransactionJMXClient.java @@ -7,6 +7,7 @@ */ package org.opendaylight.controller.config.util; +import java.util.Map; import java.util.Set; import javax.management.Attribute; @@ -26,19 +27,19 @@ import org.opendaylight.controller.config.api.jmx.ConfigTransactionControllerMXB 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); } @@ -54,7 +55,7 @@ public class ConfigTransactionJMXClient implements ConfigTransactionClient { @Override public CommitStatus commit() throws ConflictingVersionException, ValidationException { - return configTransactionManagerProxy + return configRegistryMXBeanProxy .commitConfig(configTransactionControllerON); } @@ -73,13 +74,13 @@ public class ConfigTransactionJMXClient implements ConfigTransactionClient { @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 @@ -91,12 +92,12 @@ public class ConfigTransactionJMXClient implements ConfigTransactionClient { @Override public void abortConfig() { - configControllerProxy.abortConfig(); + configTransactionControllerMXBeanProxy.abortConfig(); } @Override public void validateConfig() throws ValidationException { - configControllerProxy.validateConfig(); + configTransactionControllerMXBeanProxy.validateConfig(); } @Override @@ -121,12 +122,12 @@ public class ConfigTransactionJMXClient implements ConfigTransactionClient { @Override public String getTransactionName() { - return configControllerProxy.getTransactionName(); + return configTransactionControllerMXBeanProxy.getTransactionName(); } @Override public Set getAvailableModuleNames() { - return configControllerProxy.getAvailableModuleNames(); + return configTransactionControllerMXBeanProxy.getAvailableModuleNames(); } @Override @@ -136,27 +137,77 @@ public class ConfigTransactionJMXClient implements ConfigTransactionClient { @Override public Set lookupConfigBeans() { - return configControllerProxy.lookupConfigBeans(); + return configTransactionControllerMXBeanProxy.lookupConfigBeans(); } @Override public Set 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 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> getServiceMapping() { + return configTransactionControllerMXBeanProxy.getServiceMapping(); + } + + @Override + public Map lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName) { + return configTransactionControllerMXBeanProxy.lookupServiceReferencesByServiceInterfaceName(serviceInterfaceName); + } + + @Override + public Set 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 { diff --git a/opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/jolokia/ConfigRegistryJolokiaClient.java b/opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/jolokia/ConfigRegistryJolokiaClient.java index f29f0e03ac..9d55f8d529 100644 --- a/opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/jolokia/ConfigRegistryJolokiaClient.java +++ b/opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/jolokia/ConfigRegistryJolokiaClient.java @@ -8,8 +8,10 @@ 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; @@ -24,6 +26,7 @@ import org.opendaylight.controller.config.api.jmx.ConfigRegistryMXBean; import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; import org.opendaylight.controller.config.util.ConfigRegistryClient; +@Deprecated public class ConfigRegistryJolokiaClient extends ListableJolokiaClient implements ConfigRegistryClient { @@ -136,4 +139,35 @@ public class ConfigRegistryJolokiaClient extends ListableJolokiaClient 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> getServiceMapping() { + throw new UnsupportedOperationException(); + } + + @Override + public Map lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName) { + throw new UnsupportedOperationException(); + } + + @Override + public Set lookupServiceInterfaceNames(ObjectName objectName) throws InstanceNotFoundException { + throw new UnsupportedOperationException(); + } + + @Override + public String getServiceInterfaceName(String namespace, String localName) { + throw new UnsupportedOperationException(); + } } diff --git a/opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/jolokia/ConfigTransactionJolokiaClient.java b/opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/jolokia/ConfigTransactionJolokiaClient.java index f4824cd794..834e9c6845 100644 --- a/opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/jolokia/ConfigTransactionJolokiaClient.java +++ b/opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/jolokia/ConfigTransactionJolokiaClient.java @@ -8,6 +8,7 @@ package org.opendaylight.controller.config.util.jolokia; import java.util.Map; +import java.util.Set; import javax.management.Attribute; import javax.management.AttributeNotFoundException; @@ -25,6 +26,7 @@ import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; import org.opendaylight.controller.config.util.AttributeEntry; import org.opendaylight.controller.config.util.ConfigTransactionClient; +@Deprecated public class ConfigTransactionJolokiaClient extends ListableJolokiaClient implements ConfigTransactionClient { @@ -162,4 +164,54 @@ public class ConfigTransactionJolokiaClient extends ListableJolokiaClient 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> getServiceMapping() { + throw new UnsupportedOperationException(); + } + + @Override + public Map lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName) { + throw new UnsupportedOperationException(); + } + + @Override + public Set 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(); + } } diff --git a/opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/jolokia/ListableJolokiaClient.java b/opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/jolokia/ListableJolokiaClient.java index 6277f6a0e6..321d23ffdc 100644 --- a/opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/jolokia/ListableJolokiaClient.java +++ b/opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/jolokia/ListableJolokiaClient.java @@ -39,6 +39,7 @@ import org.opendaylight.controller.config.api.ValidationException.ExceptionMessa 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; diff --git a/opendaylight/config/config-util/src/test/java/org/opendaylight/controller/config/util/LookupTest.java b/opendaylight/config/config-util/src/test/java/org/opendaylight/controller/config/util/LookupTest.java index 0749204324..52e934583e 100644 --- a/opendaylight/config/config-util/src/test/java/org/opendaylight/controller/config/util/LookupTest.java +++ b/opendaylight/config/config-util/src/test/java/org/opendaylight/controller/config/util/LookupTest.java @@ -12,6 +12,7 @@ import static org.junit.Assert.fail; 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; @@ -69,9 +70,9 @@ public class LookupTest { ManagementFactory.getPlatformMBeanServer()); jolokiaTransactionClient = new ConfigTransactionJolokiaClient( jolokiaURL, testingTransactionControllerON, null); - lookupProvidersToClients = ImmutableMap - .of(testingRegistry, Sets.newHashSet(jmxRegistryClient, jolokiaRegistryClient), - testingTransactionController, Sets.newHashSet(jmxTransactionClient, jolokiaTransactionClient)); + HashSet registryClients = Sets.newHashSet(jmxRegistryClient, jolokiaRegistryClient); + HashSet configTransactionClients = Sets.newHashSet(jmxTransactionClient, jolokiaTransactionClient); + lookupProvidersToClients = ImmutableMap.of((LookupRegistry) testingRegistry, registryClients, testingTransactionController, configTransactionClients); } @After diff --git a/opendaylight/config/config-util/src/test/java/org/opendaylight/controller/config/util/TestingConfigRegistry.java b/opendaylight/config/config-util/src/test/java/org/opendaylight/controller/config/util/TestingConfigRegistry.java index d4ae42d3de..ba6262780c 100644 --- a/opendaylight/config/config-util/src/test/java/org/opendaylight/controller/config/util/TestingConfigRegistry.java +++ b/opendaylight/config/config-util/src/test/java/org/opendaylight/controller/config/util/TestingConfigRegistry.java @@ -8,6 +8,7 @@ package org.opendaylight.controller.config.util; import java.util.List; +import java.util.Map; import java.util.Set; import javax.management.InstanceNotFoundException; @@ -143,4 +144,33 @@ public class TestingConfigRegistry implements ConfigRegistryMXBean { } } + @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> getServiceMapping() { + throw new UnsupportedOperationException(); + } + + @Override + public Map lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName) { + throw new UnsupportedOperationException(); + } + + @Override + public Set lookupServiceInterfaceNames(ObjectName objectName) throws InstanceNotFoundException { + throw new UnsupportedOperationException(); + } + + @Override + public String getServiceInterfaceName(String namespace, String localName) { + throw new UnsupportedOperationException(); + } } diff --git a/opendaylight/config/config-util/src/test/java/org/opendaylight/controller/config/util/TestingConfigTransactionController.java b/opendaylight/config/config-util/src/test/java/org/opendaylight/controller/config/util/TestingConfigTransactionController.java index 67e31b05e5..0a845e1512 100644 --- a/opendaylight/config/config-util/src/test/java/org/opendaylight/controller/config/util/TestingConfigTransactionController.java +++ b/opendaylight/config/config-util/src/test/java/org/opendaylight/controller/config/util/TestingConfigTransactionController.java @@ -7,6 +7,7 @@ */ package org.opendaylight.controller.config.util; +import java.util.Map; import java.util.Set; import javax.management.InstanceAlreadyExistsException; @@ -109,4 +110,54 @@ public class TestingConfigTransactionController implements 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> getServiceMapping() { + throw new UnsupportedOperationException(); + } + + @Override + public Map lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName) { + throw new UnsupportedOperationException(); + } + + @Override + public Set 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(); + } } diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/Annotation.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/Annotation.java index 5ec359ea8d..59368e8e49 100644 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/Annotation.java +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/Annotation.java @@ -49,10 +49,13 @@ public class Annotation { Preconditions.checkNotNull(exportedClassName, "Cannot create annotation from null exportedClassName"); - List params = Lists.newArrayList(new Parameter("value", - q(qname.getLocalName()))); - params.add(new Parameter("osgiRegistrationType", exportedClassName - + ".class")); + List 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); } diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/resources/freeMarker/factory_abs_template.ftl b/opendaylight/config/yang-jmx-generator-plugin/src/main/resources/freeMarker/factory_abs_template.ftl index a331e4e0c1..37fd05bc52 100644 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/resources/freeMarker/factory_abs_template.ftl +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/resources/freeMarker/factory_abs_template.ftl @@ -6,12 +6,14 @@ package ${packageName}; { public static final java.lang.String NAME = "${globallyUniqueName}"; - private static final java.util.Set> serviceIfcs = new java.util.HashSet>(); + private static final java.util.Set> serviceIfcs; <#if providedServices??> static { + java.util.Set> serviceIfcs2 = new java.util.HashSet>(); <#list providedServices as refId> - serviceIfcs.add(${refId}); + serviceIfcs2.add(${refId}); + serviceIfcs = java.util.Collections.unmodifiableSet(serviceIfcs2); } @@ -25,6 +27,12 @@ package ${packageName}; return false; } + @Override + public java.util.Set> getImplementedServiceIntefaces() { + return serviceIfcs; + } + + @Override public ${moduleType} createModule(String instanceName, ${dependencyResolverType} dependencyResolver, ${bundleContextType} bundleContext) { return instantiateModule(instanceName, dependencyResolver, bundleContext); diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/JMXGeneratorTest.java b/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/JMXGeneratorTest.java index 1945cac1c2..3ef406694a 100644 --- a/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/JMXGeneratorTest.java +++ b/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/JMXGeneratorTest.java @@ -438,11 +438,11 @@ public class JMXGeneratorTest extends AbstractGeneratorTest { "public static final java.lang.String NAME=\"threadfactory-naming\""); assertDeclaredField( fieldDeclarations, - "private static final java.util.Set> serviceIfcs=new java.util.HashSet>()"); + "private static final java.util.Set> 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,