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=51cef4d3ea9e834d8beca9b8bcaa7ddbe2cb01d6;hb=81674d6fd50b419b868d0851062e23f34b34557d;hp=bf35fd1ed86f6b8249dcb4a7ca386d85ad2a53d1;hpb=986d8ca7ceae77314cc3e63461b960a28a032955;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..51cef4d3ea 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * Copyright (c) 2013, 2017 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, @@ -7,6 +7,19 @@ */ package org.opendaylight.controller.config.manager.impl; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import java.util.AbstractMap.SimpleImmutableEntry; +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,37 +39,89 @@ 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 LOG = 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 + // validator of incoming ObjectNames - throws InstanceNotFoundException if not + // found either in registry or transaction private final LookupRegistry lookupRegistry; private final ServiceReferenceRegistrator serviceReferenceRegistrator; // helper method for getting QName of SI from namespace + local name - private final Map> namespacesToAnnotations; + 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<>(); private final boolean writable; - private final Map> mBeans = new HashMap<>(); + private final Map> + managementBeans = new HashMap<>(); + + private ServiceReferenceRegistryImpl(final Map factories, + final LookupRegistry lookupRegistry, + final ServiceReferenceTransactionRegistratorFactory serviceReferenceRegistratorFactory, + final boolean writable) { + this.factories = factories; + this.writable = writable; + this.lookupRegistry = lookupRegistry; + + this.serviceReferenceRegistrator = serviceReferenceRegistratorFactory.create(); + + Map> modifiableFactoryNamesToQNames = new HashMap<>(); + Set allAnnotations = new HashSet<>(); + Set allQNameSet = new HashSet<>(); + + for (Entry entry : factories.entrySet()) { + if (!entry.getKey().equals(entry.getValue().getImplementationName())) { + LOG.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 names = InterfacesHelper.getQNames(siAnnotations); + allAnnotations.addAll(siAnnotations); + allQNameSet.addAll(names); + modifiableFactoryNamesToQNames.put(entry.getKey(), names); + } + this.factoryNamesToQNames = ImmutableMap.copyOf(modifiableFactoryNamesToQNames); + this.allQNames = ImmutableSet.copyOf(allQNameSet); + // fill namespacesToAnnotations + Map> + modifiableNamespacesToAnnotations = new HashMap<>(); + Map + modifiableServiceQNamesToAnnotations = new HashMap<>(); + for (ServiceInterfaceAnnotation sia : allAnnotations) { + Map ofNamespace = modifiableNamespacesToAnnotations + .computeIfAbsent(sia.namespace(), k -> new HashMap<>()); + if (ofNamespace.containsKey(sia.localName())) { + LOG.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 = ImmutableMap.copyOf(modifiableNamespacesToAnnotations); + this.serviceQNamesToAnnotations = ImmutableMap.copyOf(modifiableServiceQNamesToAnnotations); + LOG.trace("factoryNamesToQNames:{}", this.factoryNamesToQNames); + } /** - * Static constructor for config registry. Since only transaction can write to this registry, it will - * return blank state. + * Static constructor for config registry. Since only transaction can write to + * this registry, it will return blank state. + * + * @return service reference registry */ public static CloseableServiceReferenceReadableRegistry createInitialSRLookupRegistry() { // since this is initial state, just throw exception: @@ -67,22 +132,23 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe } @Override - public Set lookupConfigBeans(String moduleName) { + public Set lookupConfigBeans(final String moduleName) { throw new UnsupportedOperationException(); } @Override - public Set lookupConfigBeans(String moduleName, String instanceName) { + public Set lookupConfigBeans(final String moduleName, final String instanceName) { throw new UnsupportedOperationException(); } @Override - public ObjectName lookupConfigBean(String moduleName, String instanceName) throws InstanceNotFoundException { + public ObjectName lookupConfigBean(final String moduleName, final String instanceName) + throws InstanceNotFoundException { throw new UnsupportedOperationException(); } @Override - public void checkConfigBeanExists(ObjectName objectName) throws InstanceNotFoundException { + public void checkConfigBeanExists(final ObjectName objectName) throws InstanceNotFoundException { throw new InstanceNotFoundException("Cannot find " + objectName + " - Tried to use mocking registry"); } @@ -92,49 +158,55 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe } @Override - public String toString() { - return "initial"; + public Set lookupRuntimeBeans() { + throw new UnsupportedOperationException(); } - }; - ServiceReferenceTransactionRegistratorFactory serviceReferenceRegistratorFactory = new ServiceReferenceTransactionRegistratorFactory(){ + @Override - public ServiceReferenceRegistrator create() { - return new ServiceReferenceRegistrator() { - @Override - public String getNullableTransactionName() { - throw new UnsupportedOperationException(); - } - - @Override - public ServiceReferenceJMXRegistration registerMBean(ServiceReferenceMXBeanImpl object, ObjectName on) throws InstanceAlreadyExistsException { - throw new UnsupportedOperationException(); - } - - @Override - public void close() { - - } - }; + public Set lookupRuntimeBeans(final String moduleName, final String instanceName) { + throw new UnsupportedOperationException(); + } + + @Override + public String toString() { + return "initial"; } }; + + ServiceReferenceTransactionRegistratorFactory serviceReferenceRegistratorFactory = + () -> new ServiceReferenceRegistrator() { + @Override + public String getNullableTransactionName() { + throw new UnsupportedOperationException(); + } + + @Override + public ServiceReferenceJMXRegistration registerMBean(final ServiceReferenceMXBeanImpl object, + final ObjectName on) throws InstanceAlreadyExistsException { + throw new UnsupportedOperationException(); + } + + @Override + public void close() { + } + }; return new ServiceReferenceRegistryImpl(Collections.emptyMap(), lookupRegistry, serviceReferenceRegistratorFactory, false); } - /** - * Static constructor for transaction controller. Take current state as seen by config registry, allow writing new data. - */ - public static ServiceReferenceWritableRegistry createSRWritableRegistry(ServiceReferenceReadableRegistry oldReadableRegistry, - ConfigTransactionLookupRegistry txLookupRegistry, - Map> currentlyRegisteredFactories) { + public static SearchableServiceReferenceWritableRegistry createSRWritableRegistry( + final ServiceReferenceReadableRegistry oldReadableRegistry, + final ConfigTransactionLookupRegistry txLookupRegistry, + final Map> currentlyRegisteredFactories) { if (txLookupRegistry == null) { throw new IllegalArgumentException("txLookupRegistry is null"); } ServiceReferenceRegistryImpl old = (ServiceReferenceRegistryImpl) oldReadableRegistry; Map factories = extractFactoriesMap(currentlyRegisteredFactories); - ServiceReferenceTransactionRegistratorFactory serviceReferenceRegistratorFactory = new ServiceReferenceTransactionRegistratorFactoryImpl( - txLookupRegistry.getTxModuleJMXRegistrator(), txLookupRegistry.getTxModuleJMXRegistrator().getTransactionName()); + ServiceReferenceTransactionRegistratorFactory serviceReferenceRegistratorFactory = + new ServiceReferenceTransactionRegistratorFactoryImpl(txLookupRegistry.getTxModuleJMXRegistrator(), + txLookupRegistry.getTxModuleJMXRegistrator().getTransactionName()); ServiceReferenceRegistryImpl newRegistry = new ServiceReferenceRegistryImpl(factories, txLookupRegistry, serviceReferenceRegistratorFactory, true); copy(old, newRegistry, txLookupRegistry.getTransactionIdentifier().getName()); @@ -143,42 +215,54 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe /** * Copy back state to config registry after commit. + * + * @param oldWritableRegistry + * old registry + * @param lookupRegistry + * lookup registry + * @param baseJMXRegistrator + * JMX registrator + * @return service reference */ - public static CloseableServiceReferenceReadableRegistry createSRReadableRegistry(ServiceReferenceWritableRegistry oldWritableRegistry, - LookupRegistry lookupRegistry, BaseJMXRegistrator baseJMXRegistrator) { + public static CloseableServiceReferenceReadableRegistry createSRReadableRegistry( + final ServiceReferenceWritableRegistry oldWritableRegistry, final LookupRegistry lookupRegistry, + final BaseJMXRegistrator baseJMXRegistrator) { ServiceReferenceRegistryImpl old = (ServiceReferenceRegistryImpl) oldWritableRegistry; - // even if factories do change, nothing in the mapping can change between transactions - ServiceReferenceTransactionRegistratorFactory serviceReferenceRegistratorFactory = new ServiceReferenceTransactionRegistratorFactoryImpl(baseJMXRegistrator); + // even if factories do change, nothing in the mapping can change between + // transactions + ServiceReferenceTransactionRegistratorFactory serviceReferenceRegistratorFactory = + new ServiceReferenceTransactionRegistratorFactoryImpl(baseJMXRegistrator); ServiceReferenceRegistryImpl newRegistry = new ServiceReferenceRegistryImpl(old.factories, lookupRegistry, serviceReferenceRegistratorFactory, false); copy(old, newRegistry, null); return newRegistry; } - /** - * Fill refNames and mBeans maps from old instance - */ - private static void copy(ServiceReferenceRegistryImpl old, ServiceReferenceRegistryImpl newRegistry, String nullableDstTransactionName) { - for (Entry> refNameEntry : old.mBeans.entrySet()) { + private static void copy(final ServiceReferenceRegistryImpl old, final ServiceReferenceRegistryImpl newRegistry, + final String nullableDstTransactionName) { + for (Entry> + refNameEntry : old.managementBeans.entrySet()) { ObjectName currentImplementation; ObjectName currentImplementationSrc = refNameEntry.getValue().getKey().getCurrentImplementation(); if (nullableDstTransactionName != null) { - currentImplementation = ObjectNameUtil.withTransactionName(currentImplementationSrc, nullableDstTransactionName); + currentImplementation = ObjectNameUtil.withTransactionName(currentImplementationSrc, + nullableDstTransactionName); } else { currentImplementation = ObjectNameUtil.withoutTransactionName(currentImplementationSrc); } try { boolean skipChecks = true; newRegistry.saveServiceReference(refNameEntry.getKey(), currentImplementation, skipChecks); - } catch (InstanceNotFoundException e) { - logger.error("Cannot save service reference({}, {})", refNameEntry.getKey(), currentImplementation); + } catch (final InstanceNotFoundException e) { + LOG.error("Cannot save service reference({}, {})", refNameEntry.getKey(), currentImplementation); throw new IllegalStateException("Possible code error", e); } } } - private static Map extractFactoriesMap(Map> currentlyRegisteredFactories) { + private static Map extractFactoriesMap( + final Map> currentlyRegisteredFactories) { Map result = new HashMap<>(); for (Entry> entry : currentlyRegisteredFactories.entrySet()) { result.put(entry.getKey(), entry.getValue().getKey()); @@ -186,64 +270,26 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe return result; } - private ServiceReferenceRegistryImpl(Map factories, LookupRegistry lookupRegistry, - ServiceReferenceTransactionRegistratorFactory serviceReferenceRegistratorFactory, - boolean writable) { - this.factories = factories; - this.writable = writable; - this.lookupRegistry = lookupRegistry; - - this.serviceReferenceRegistrator = serviceReferenceRegistratorFactory.create(); - - Map> modifiableFactoryNamesToQNames = 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); - modifiableFactoryNamesToQNames.put(entry.getKey(), Collections.unmodifiableSet(qNames)); - } - this.factoryNamesToQNames = Collections.unmodifiableMap(modifiableFactoryNamesToQNames); - this.allQNames = Collections.unmodifiableSet(allQNames); - // fill namespacesToAnnotations - Map> modifiableNamespacesToAnnotations = - new HashMap<>(); - for (ServiceInterfaceAnnotation sia : allAnnotations) { - Map ofNamespace = modifiableNamespacesToAnnotations.get(sia.namespace()); - if (ofNamespace == null) { - ofNamespace = new HashMap<>(); - 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 {}", - sia.namespace(), sia.localName(), modifiableNamespacesToAnnotations); - throw new IllegalArgumentException("Conflict between local names in " + sia.namespace() + " : " + sia.localName()); - } - ofNamespace.put(sia.localName(), sia); + @Override + public Map findServiceInterfaces( + final ModuleIdentifier moduleIdentifier) { + Map result = modulesToServiceRef + .get(moduleIdentifier); + if (result == null) { + return Collections.emptyMap(); } - this.namespacesToAnnotations = Collections.unmodifiableMap(modifiableNamespacesToAnnotations); - // copy refNames - logger.trace("factoryNamesToQNames:{}", this.factoryNamesToQNames); + return Collections.unmodifiableMap(result); } - @Override - public synchronized Set lookupServiceInterfaceNames(ObjectName objectName) throws InstanceNotFoundException { + public synchronized Set lookupServiceInterfaceNames(final 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 {}", + LOG.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); } @@ -251,15 +297,15 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe } @Override - public synchronized String getServiceInterfaceName(String namespace, String localName) { + public synchronized String getServiceInterfaceName(final String namespace, final String localName) { Map ofNamespace = namespacesToAnnotations.get(namespace); if (ofNamespace == null) { - logger.error("Cannot find namespace {} in {}", namespace, namespacesToAnnotations); + LOG.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); + LOG.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(); @@ -268,103 +314,103 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe // reading: @Override - public synchronized Map> getServiceMapping() { + public synchronized Map> getServiceMapping() { Map> result = new HashMap<>(); - for (Entry entry: refNames.entrySet()) { - String qName = entry.getKey().getServiceInterfaceName(); - Map innerMap = result.get(qName); - if (innerMap == null) { - innerMap = new HashMap<>(); - result.put(qName, innerMap); - } + for (Entry entry : refNames.entrySet()) { + String name = entry.getKey().getServiceInterfaceQName(); + Map innerMap = result.computeIfAbsent(name, k -> new HashMap<>()); innerMap.put(entry.getKey().getRefName(), getObjectName(entry.getValue())); } return result; } - private ObjectName getObjectName(ModuleIdentifier moduleIdentifier) { + private ObjectName getObjectName(final ModuleIdentifier moduleIdentifier) { ObjectName on; try { on = lookupRegistry.lookupConfigBean(moduleIdentifier.getFactoryName(), moduleIdentifier.getInstanceName()); - } catch (InstanceNotFoundException e) { - logger.error("Cannot find instance {}", moduleIdentifier); + } catch (final InstanceNotFoundException e) { + LOG.error("Cannot find instance {}", moduleIdentifier); throw new IllegalStateException("Cannot find instance " + moduleIdentifier, e); } return on; } @Override - public synchronized ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceQName, String refName) { + public synchronized ObjectName lookupConfigBeanByServiceInterfaceName(final String serviceInterfaceQName, + final String refName) { 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); + LOG.error("Cannot find qname {} and refName {} in {}", serviceInterfaceQName, refName, refName); throw new IllegalArgumentException("Cannot find " + serviceReference); } return getObjectName(moduleIdentifier); } @Override - public synchronized Map lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceQName) { + public synchronized Map lookupServiceReferencesByServiceInterfaceName( + final String serviceInterfaceQName) { Map> serviceMapping = getServiceMapping(); Map innerMap = serviceMapping.get(serviceInterfaceQName); if (innerMap == null) { - logger.error("Cannot find qname {} in {}", serviceInterfaceQName, refNames); + LOG.error("Cannot find qname {} in {}", serviceInterfaceQName, refNames); throw new IllegalArgumentException("Cannot find " + serviceInterfaceQName); } return innerMap; } @Override - public synchronized ObjectName getServiceReference(String serviceInterfaceQName, String refName) throws InstanceNotFoundException { + public synchronized ObjectName getServiceReference(final String serviceInterfaceQName, final String refName) + throws InstanceNotFoundException { ServiceReference serviceReference = new ServiceReference(serviceInterfaceQName, refName); - if (mBeans.containsKey(serviceReference) == false) { + if (!managementBeans.containsKey(serviceReference)) { throw new InstanceNotFoundException("Cannot find " + serviceReference); } return getServiceON(serviceReference); } @Override - public synchronized void checkServiceReferenceExists(ObjectName objectName) throws InstanceNotFoundException { + public synchronized void checkServiceReferenceExists(final ObjectName objectName) throws InstanceNotFoundException { String actualTransactionName = ObjectNameUtil.getTransactionName(objectName); String expectedTransactionName = serviceReferenceRegistrator.getNullableTransactionName(); - if (writable & actualTransactionName == null || (writable && actualTransactionName.equals(expectedTransactionName) == false)) { + if (writable && actualTransactionName == null + || writable && !actualTransactionName.equals(expectedTransactionName)) { throw new IllegalArgumentException("Mismatched transaction name in " + objectName); } String serviceQName = ObjectNameUtil.getServiceQName(objectName); String referenceName = ObjectNameUtil.getReferenceName(objectName); ServiceReference serviceReference = new ServiceReference(serviceQName, referenceName); - if (refNames.containsKey(serviceReference) == false) { - logger.warn("Cannot find {} in {}", serviceReference, refNames); + if (!refNames.containsKey(serviceReference)) { + LOG.warn("Cannot find {} in {}", serviceReference, refNames); throw new InstanceNotFoundException("Service reference not found:" + objectName); } } // writing: - private void assertWritable() { - if (writable == false) { + if (!writable) { throw new IllegalStateException("Cannot write to readable registry"); } } @Override - public synchronized ObjectName saveServiceReference(String serviceInterfaceName, String refName, ObjectName moduleON) throws InstanceNotFoundException { + public synchronized ObjectName saveServiceReference(final String serviceInterfaceName, final String refName, + final ObjectName moduleON) throws InstanceNotFoundException { assertWritable(); ServiceReference serviceReference = new ServiceReference(serviceInterfaceName, refName); return saveServiceReference(serviceReference, moduleON); } - private synchronized ObjectName saveServiceReference(ServiceReference serviceReference, ObjectName moduleON) - throws InstanceNotFoundException{ + private synchronized ObjectName saveServiceReference(final ServiceReference serviceReference, + final ObjectName moduleON) throws InstanceNotFoundException { return saveServiceReference(serviceReference, moduleON, false); } - private synchronized ObjectName saveServiceReference(ServiceReference serviceReference, ObjectName moduleON, - boolean skipChecks) throws InstanceNotFoundException { + private synchronized ObjectName saveServiceReference(final ServiceReference serviceReference, + final ObjectName moduleON, final boolean skipChecks) throws InstanceNotFoundException { // make sure it is found - if (skipChecks == false) { + if (!skipChecks) { lookupRegistry.checkConfigBeanExists(moduleON); } String factoryName = ObjectNameUtil.getFactoryName(moduleON); @@ -374,87 +420,85 @@ 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(), + LOG.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()); + 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())) { + LOG.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()); } - // create service reference object name, put to mBeans ObjectName result = getServiceON(serviceReference); - Entry mxBeanEntry = mBeans.get(serviceReference); + Entry mxBeanEntry = + managementBeans.get(serviceReference); if (mxBeanEntry == null) { // create dummy mx bean ServiceReferenceMXBeanImpl dummyMXBean = new ServiceReferenceMXBeanImpl(moduleON); ServiceReferenceJMXRegistration dummyMXBeanRegistration; try { dummyMXBeanRegistration = serviceReferenceRegistrator.registerMBean(dummyMXBean, result); - } catch (InstanceAlreadyExistsException e) { + } catch (final InstanceAlreadyExistsException e) { throw new IllegalStateException("Possible error in code. Cannot register " + result, e); } - mBeans.put(serviceReference, createMXBeanEntry(dummyMXBean, dummyMXBeanRegistration)); + managementBeans.put(serviceReference, new SimpleImmutableEntry<>(dummyMXBean, dummyMXBeanRegistration)); } else { // update mxBeanEntry.getKey().setCurrentImplementation(moduleON); } // save to refNames refNames.put(serviceReference, moduleIdentifier); + Map refNamesToAnnotations = modulesToServiceRef + .computeIfAbsent(moduleIdentifier, k -> new HashMap<>()); + + ServiceInterfaceAnnotation annotation = serviceQNamesToAnnotations + .get(serviceReference.getServiceInterfaceQName()); + Preconditions.checkNotNull(annotation, + "Possible error in code, cannot find annotation for " + serviceReference); + refNamesToAnnotations.put(annotation, serviceReference.getRefName()); return result; } - private Entry createMXBeanEntry( - final ServiceReferenceMXBeanImpl mxBean, final ServiceReferenceJMXRegistration registration) { - return new Entry() { - @Override - public ServiceReferenceMXBeanImpl getKey() { - return mxBean; - } - - @Override - public ServiceReferenceJMXRegistration getValue() { - return registration; - } - - @Override - public ServiceReferenceJMXRegistration setValue(ServiceReferenceJMXRegistration value) { - throw new UnsupportedOperationException(); - } - }; - } - - private ObjectName getServiceON(ServiceReference serviceReference) { + private ObjectName getServiceON(final ServiceReference serviceReference) { if (writable) { return ObjectNameUtil.createTransactionServiceON(serviceReferenceRegistrator.getNullableTransactionName(), - serviceReference.getServiceInterfaceName(), serviceReference.getRefName()); - } else { - return ObjectNameUtil.createReadOnlyServiceON(serviceReference.getServiceInterfaceName(), serviceReference.getRefName()); + serviceReference.getServiceInterfaceQName(), serviceReference.getRefName()); } + + return ObjectNameUtil.createReadOnlyServiceON(serviceReference.getServiceInterfaceQName(), + serviceReference.getRefName()); } @Override - public synchronized void removeServiceReference(String serviceInterfaceName, String refName) throws InstanceNotFoundException{ + public synchronized void removeServiceReference(final String serviceInterfaceName, final String refName) + throws InstanceNotFoundException { ServiceReference serviceReference = new ServiceReference(serviceInterfaceName, refName); removeServiceReference(serviceReference); } - private synchronized void removeServiceReference(ServiceReference serviceReference) throws InstanceNotFoundException { - logger.debug("Removing service reference {} from {}", serviceReference, this); + private synchronized void removeServiceReference(final ServiceReference serviceReference) + throws InstanceNotFoundException { + LOG.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())) { + LOG.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()); + if (removed == null) { + throw new InstanceNotFoundException("Cannot find " + serviceReference.getServiceInterfaceQName()); } - Entry entry = mBeans.remove(serviceReference); + Entry entry = + managementBeans.remove(serviceReference); if (entry == null) { throw new IllegalStateException("Possible code error: cannot remove from mBeans: " + serviceReference); } @@ -464,33 +508,44 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe @Override public synchronized void removeAllServiceReferences() { assertWritable(); - for (ServiceReference serviceReference: mBeans.keySet()) { + for (ServiceReference serviceReference : managementBeans.keySet()) { try { removeServiceReference(serviceReference); - } catch (InstanceNotFoundException e) { + } catch (final InstanceNotFoundException e) { throw new IllegalStateException("Possible error in code", e); } } } @Override - public synchronized boolean removeServiceReferences(ObjectName moduleObjectName) throws InstanceNotFoundException { + public synchronized boolean removeServiceReferences(final 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(final ObjectName moduleObjectName, final Set names) + throws InstanceNotFoundException { + ObjectNameUtil.checkType(moduleObjectName, ObjectNameUtil.TYPE_MODULE); assertWritable(); - Set serviceReferencesLinkingTo = findServiceReferencesLinkingTo(moduleObjectName); + Set serviceReferencesLinkingTo = findServiceReferencesLinkingTo(moduleObjectName, names); for (ServiceReference sr : serviceReferencesLinkingTo) { removeServiceReference(sr); } - return serviceReferencesLinkingTo.isEmpty() == false; + return !serviceReferencesLinkingTo.isEmpty(); } - private synchronized Set findServiceReferencesLinkingTo(ObjectName moduleObjectName) throws InstanceNotFoundException { - lookupRegistry.checkConfigBeanExists(moduleObjectName); + private Set findServiceReferencesLinkingTo(final ObjectName moduleObjectName, + final 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); - throw new IllegalStateException("Possible error in code: cannot find annotations of existing factory " + factoryName); + LOG.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); ModuleIdentifier moduleIdentifier = new ModuleIdentifier(factoryName, instanceName); @@ -503,14 +558,10 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe return result; } - @Override public String toString() { - return "ServiceReferenceRegistryImpl{" + - "lookupRegistry=" + lookupRegistry + - "refNames=" + refNames + - ", factoryNamesToQNames=" + factoryNamesToQNames + - '}'; + return "ServiceReferenceRegistryImpl{" + "lookupRegistry=" + lookupRegistry + "refNames=" + refNames + + ", factoryNamesToQNames=" + factoryNamesToQNames + '}'; } @Override