X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fconfig%2Fconfig-manager%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fconfig%2Fmanager%2Fimpl%2FServiceReferenceRegistryImpl.java;h=0f881e95add37a0ac925ff1b835ba2813cc6c4b0;hb=8161319be53a57e3ac22ba72f267483526e11e0d;hp=bf35fd1ed86f6b8249dcb4a7ca386d85ad2a53d1;hpb=37cf6538c44f41123b2261dd158f91078b07fb4f;p=controller.git 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 index bf35fd1ed8..0f881e95ad 100644 --- 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 @@ -7,6 +7,17 @@ */ package org.opendaylight.controller.config.manager.impl; +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import javax.management.InstanceAlreadyExistsException; +import javax.management.InstanceNotFoundException; +import javax.management.ObjectName; import org.opendaylight.controller.config.api.LookupRegistry; import org.opendaylight.controller.config.api.ModuleIdentifier; import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry; @@ -26,18 +37,8 @@ import org.osgi.framework.BundleContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.management.InstanceAlreadyExistsException; -import javax.management.InstanceNotFoundException; -import javax.management.ObjectName; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceReadableRegistry, ServiceReferenceWritableRegistry { - private static final Logger logger = LoggerFactory.getLogger(ServiceReferenceRegistryImpl.class); +public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceReadableRegistry, SearchableServiceReferenceWritableRegistry { + private static final Logger LOGGER = LoggerFactory.getLogger(ServiceReferenceRegistryImpl.class); private final Map factories; private final Map> factoryNamesToQNames; @@ -46,8 +47,11 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe private final ServiceReferenceRegistrator serviceReferenceRegistrator; // helper method for getting QName of SI from namespace + local name private final Map> namespacesToAnnotations; + private final Map serviceQNamesToAnnotations; // all Service Interface qNames for sanity checking private final Set allQNames; + Map> modulesToServiceRef = new HashMap<>(); + // actual reference database private final Map refNames = new HashMap<>(); @@ -124,7 +128,7 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe /** * Static constructor for transaction controller. Take current state as seen by config registry, allow writing new data. */ - public static ServiceReferenceWritableRegistry createSRWritableRegistry(ServiceReferenceReadableRegistry oldReadableRegistry, + public static SearchableServiceReferenceWritableRegistry createSRWritableRegistry(ServiceReferenceReadableRegistry oldReadableRegistry, ConfigTransactionLookupRegistry txLookupRegistry, Map> currentlyRegisteredFactories) { @@ -172,7 +176,7 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe boolean skipChecks = true; newRegistry.saveServiceReference(refNameEntry.getKey(), currentImplementation, skipChecks); } catch (InstanceNotFoundException e) { - logger.error("Cannot save service reference({}, {})", refNameEntry.getKey(), currentImplementation); + LOGGER.error("Cannot save service reference({}, {})", refNameEntry.getKey(), currentImplementation); throw new IllegalStateException("Possible code error", e); } } @@ -197,26 +201,26 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe Map> modifiableFactoryNamesToQNames = new HashMap<>(); Set allAnnotations = new HashSet<>(); - Set allQNames = new HashSet<>(); + Set allQNameSet = 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); + 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()); - } + Set qNames = InterfacesHelper.getQNames(siAnnotations); allAnnotations.addAll(siAnnotations); - allQNames.addAll(qNames); + allQNameSet.addAll(qNames); modifiableFactoryNamesToQNames.put(entry.getKey(), Collections.unmodifiableSet(qNames)); } this.factoryNamesToQNames = Collections.unmodifiableMap(modifiableFactoryNamesToQNames); - this.allQNames = Collections.unmodifiableSet(allQNames); + this.allQNames = Collections.unmodifiableSet(allQNameSet); // fill namespacesToAnnotations Map> modifiableNamespacesToAnnotations = new HashMap<>(); + Map modifiableServiceQNamesToAnnotations = new HashMap<>(); for (ServiceInterfaceAnnotation sia : allAnnotations) { Map ofNamespace = modifiableNamespacesToAnnotations.get(sia.namespace()); if (ofNamespace == null) { @@ -224,17 +228,26 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe modifiableNamespacesToAnnotations.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 {}", + LOGGER.error("Cannot construct namespacesToAnnotations map, conflict between local names in {}, offending local name: {}, map so far {}", sia.namespace(), sia.localName(), modifiableNamespacesToAnnotations); throw new IllegalArgumentException("Conflict between local names in " + sia.namespace() + " : " + sia.localName()); } ofNamespace.put(sia.localName(), sia); + modifiableServiceQNamesToAnnotations.put(sia.value(), sia); } this.namespacesToAnnotations = Collections.unmodifiableMap(modifiableNamespacesToAnnotations); - // copy refNames - logger.trace("factoryNamesToQNames:{}", this.factoryNamesToQNames); + this.serviceQNamesToAnnotations = Collections.unmodifiableMap(modifiableServiceQNamesToAnnotations); + LOGGER.trace("factoryNamesToQNames:{}", this.factoryNamesToQNames); } + @Override + public Map findServiceInterfaces(ModuleIdentifier moduleIdentifier) { + Map result = modulesToServiceRef.get(moduleIdentifier); + if (result == null) { + return Collections.emptyMap(); + } + return Collections.unmodifiableMap(result); + } @Override public synchronized Set lookupServiceInterfaceNames(ObjectName objectName) throws InstanceNotFoundException { @@ -243,7 +256,7 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe 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 {}", + 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); } @@ -254,12 +267,12 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe public synchronized String getServiceInterfaceName(String namespace, String localName) { Map ofNamespace = namespacesToAnnotations.get(namespace); if (ofNamespace == null) { - logger.error("Cannot find namespace {} in {}", namespace, namespacesToAnnotations); + 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); + 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(); @@ -271,7 +284,7 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe public synchronized Map> getServiceMapping() { Map> result = new HashMap<>(); for (Entry entry: refNames.entrySet()) { - String qName = entry.getKey().getServiceInterfaceName(); + String qName = entry.getKey().getServiceInterfaceQName(); Map innerMap = result.get(qName); if (innerMap == null) { innerMap = new HashMap<>(); @@ -287,7 +300,7 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe try { on = lookupRegistry.lookupConfigBean(moduleIdentifier.getFactoryName(), moduleIdentifier.getInstanceName()); } catch (InstanceNotFoundException e) { - logger.error("Cannot find instance {}", moduleIdentifier); + LOGGER.error("Cannot find instance {}", moduleIdentifier); throw new IllegalStateException("Cannot find instance " + moduleIdentifier, e); } return on; @@ -298,7 +311,7 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe ServiceReference serviceReference = new ServiceReference(serviceInterfaceQName, refName); ModuleIdentifier moduleIdentifier = refNames.get(serviceReference); if (moduleIdentifier == null) { - logger.error("Cannot find qname {} and refName {} in {}", serviceInterfaceQName, refName, refName); + LOGGER.error("Cannot find qname {} and refName {} in {}", serviceInterfaceQName, refName, refName); throw new IllegalArgumentException("Cannot find " + serviceReference); } return getObjectName(moduleIdentifier); @@ -309,7 +322,7 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe Map> serviceMapping = getServiceMapping(); Map innerMap = serviceMapping.get(serviceInterfaceQName); if (innerMap == null) { - logger.error("Cannot find qname {} in {}", serviceInterfaceQName, refNames); + LOGGER.error("Cannot find qname {} in {}", serviceInterfaceQName, refNames); throw new IllegalArgumentException("Cannot find " + serviceInterfaceQName); } return innerMap; @@ -335,7 +348,7 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe String referenceName = ObjectNameUtil.getReferenceName(objectName); ServiceReference serviceReference = new ServiceReference(serviceQName, referenceName); if (refNames.containsKey(serviceReference) == false) { - logger.warn("Cannot find {} in {}", serviceReference, refNames); + LOGGER.warn("Cannot find {} in {}", serviceReference, refNames); throw new InstanceNotFoundException("Service reference not found:" + objectName); } } @@ -374,14 +387,14 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe // check that service interface name exist Set serviceInterfaceQNames = factoryNamesToQNames.get(moduleIdentifier.getFactoryName()); if (serviceInterfaceQNames == null) { - logger.error("Possible error in code: cannot find factoryName {} in {}, {}", moduleIdentifier.getFactoryName(), + LOGGER.error("Possible error in code: cannot find factoryName {} in {}, {}", moduleIdentifier.getFactoryName(), factoryNamesToQNames, moduleIdentifier); throw new IllegalStateException("Possible error in code: cannot find annotations of existing factory " + moduleIdentifier.getFactoryName()); } // supplied serviceInterfaceName must exist in this collection - if (serviceInterfaceQNames.contains(serviceReference.getServiceInterfaceName()) == false) { - logger.error("Cannot find qName {} with factory name {}, found {}", serviceReference.getServiceInterfaceName(), moduleIdentifier.getFactoryName(), serviceInterfaceQNames); - throw new IllegalArgumentException("Cannot find service interface " + serviceReference.getServiceInterfaceName() + " within factory " + moduleIdentifier.getFactoryName()); + if (serviceInterfaceQNames.contains(serviceReference.getServiceInterfaceQName()) == false) { + LOGGER.error("Cannot find qName {} with factory name {}, found {}", serviceReference.getServiceInterfaceQName(), moduleIdentifier.getFactoryName(), serviceInterfaceQNames); + throw new IllegalArgumentException("Cannot find service interface " + serviceReference.getServiceInterfaceQName() + " within factory " + moduleIdentifier.getFactoryName()); } @@ -404,6 +417,15 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe } // save to refNames refNames.put(serviceReference, moduleIdentifier); + Map refNamesToAnnotations = modulesToServiceRef.get(moduleIdentifier); + if (refNamesToAnnotations == null){ + refNamesToAnnotations = new HashMap<>(); + modulesToServiceRef.put(moduleIdentifier, refNamesToAnnotations); + } + + ServiceInterfaceAnnotation annotation = serviceQNamesToAnnotations.get(serviceReference.getServiceInterfaceQName()); + checkNotNull(annotation, "Possible error in code, cannot find annotation for " + serviceReference); + refNamesToAnnotations.put(annotation, serviceReference.getRefName()); return result; } @@ -430,9 +452,9 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe private ObjectName getServiceON(ServiceReference serviceReference) { if (writable) { return ObjectNameUtil.createTransactionServiceON(serviceReferenceRegistrator.getNullableTransactionName(), - serviceReference.getServiceInterfaceName(), serviceReference.getRefName()); + serviceReference.getServiceInterfaceQName(), serviceReference.getRefName()); } else { - return ObjectNameUtil.createReadOnlyServiceON(serviceReference.getServiceInterfaceName(), serviceReference.getRefName()); + return ObjectNameUtil.createReadOnlyServiceON(serviceReference.getServiceInterfaceQName(), serviceReference.getRefName()); } } @@ -443,16 +465,16 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe } private synchronized void removeServiceReference(ServiceReference serviceReference) throws InstanceNotFoundException { - logger.debug("Removing service reference {} from {}", serviceReference, this); + LOGGER.debug("Removing service reference {} from {}", serviceReference, this); assertWritable(); // is the qName known? - if (allQNames.contains(serviceReference.getServiceInterfaceName()) == false) { - logger.error("Cannot find qname {} in {}", serviceReference.getServiceInterfaceName(), allQNames); - throw new IllegalArgumentException("Cannot find service interface " + serviceReference.getServiceInterfaceName()); + if (allQNames.contains(serviceReference.getServiceInterfaceQName()) == false) { + LOGGER.error("Cannot find qname {} in {}", serviceReference.getServiceInterfaceQName(), allQNames); + throw new IllegalArgumentException("Cannot find service interface " + serviceReference.getServiceInterfaceQName()); } ModuleIdentifier removed = refNames.remove(serviceReference); if (removed == null){ - throw new InstanceNotFoundException("Cannot find " + serviceReference.getServiceInterfaceName()); + throw new InstanceNotFoundException("Cannot find " + serviceReference.getServiceInterfaceQName()); } Entry entry = mBeans.remove(serviceReference); if (entry == null) { @@ -475,21 +497,28 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe @Override public synchronized boolean removeServiceReferences(ObjectName moduleObjectName) throws InstanceNotFoundException { + lookupRegistry.checkConfigBeanExists(moduleObjectName); + String factoryName = ObjectNameUtil.getFactoryName(moduleObjectName); + // check that service interface name exist + Set serviceInterfaceQNames = factoryNamesToQNames.get(factoryName); + return removeServiceReferences(moduleObjectName, serviceInterfaceQNames); + } + + + private boolean removeServiceReferences(ObjectName moduleObjectName, Set qNames) throws InstanceNotFoundException { + ObjectNameUtil.checkType(moduleObjectName, ObjectNameUtil.TYPE_MODULE); assertWritable(); - Set serviceReferencesLinkingTo = findServiceReferencesLinkingTo(moduleObjectName); + Set serviceReferencesLinkingTo = findServiceReferencesLinkingTo(moduleObjectName, qNames); for (ServiceReference sr : serviceReferencesLinkingTo) { removeServiceReference(sr); } return serviceReferencesLinkingTo.isEmpty() == false; } - private synchronized Set findServiceReferencesLinkingTo(ObjectName moduleObjectName) throws InstanceNotFoundException { - lookupRegistry.checkConfigBeanExists(moduleObjectName); + private Set findServiceReferencesLinkingTo(ObjectName moduleObjectName, Set serviceInterfaceQNames) { String factoryName = ObjectNameUtil.getFactoryName(moduleObjectName); - // 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, moduleObjectName); + LOGGER.warn("Possible error in code: cannot find factoryName {} in {}, object name {}", factoryName, factoryNamesToQNames, moduleObjectName); throw new IllegalStateException("Possible error in code: cannot find annotations of existing factory " + factoryName); } String instanceName = ObjectNameUtil.getInstanceName(moduleObjectName); @@ -503,7 +532,6 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe return result; } - @Override public String toString() { return "ServiceReferenceRegistryImpl{" +