2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.controller.config.manager.impl;
10 import static com.google.common.base.Preconditions.checkNotNull;
12 import com.google.common.collect.ImmutableMap;
13 import com.google.common.collect.ImmutableSet;
14 import java.util.Collections;
15 import java.util.HashMap;
16 import java.util.HashSet;
18 import java.util.Map.Entry;
20 import javax.management.InstanceAlreadyExistsException;
21 import javax.management.InstanceNotFoundException;
22 import javax.management.ObjectName;
23 import org.opendaylight.controller.config.api.LookupRegistry;
24 import org.opendaylight.controller.config.api.ModuleIdentifier;
25 import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
26 import org.opendaylight.controller.config.api.ServiceReferenceWritableRegistry;
27 import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation;
28 import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
29 import org.opendaylight.controller.config.manager.impl.jmx.BaseJMXRegistrator;
30 import org.opendaylight.controller.config.manager.impl.jmx.ServiceReference;
31 import org.opendaylight.controller.config.manager.impl.jmx.ServiceReferenceMXBeanImpl;
32 import org.opendaylight.controller.config.manager.impl.jmx.ServiceReferenceRegistrator;
33 import org.opendaylight.controller.config.manager.impl.jmx.ServiceReferenceRegistrator.ServiceReferenceJMXRegistration;
34 import org.opendaylight.controller.config.manager.impl.jmx.ServiceReferenceRegistrator.ServiceReferenceTransactionRegistratorFactory;
35 import org.opendaylight.controller.config.manager.impl.jmx.ServiceReferenceRegistrator.ServiceReferenceTransactionRegistratorFactoryImpl;
36 import org.opendaylight.controller.config.manager.impl.util.InterfacesHelper;
37 import org.opendaylight.controller.config.spi.ModuleFactory;
38 import org.osgi.framework.BundleContext;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
42 public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceReadableRegistry, SearchableServiceReferenceWritableRegistry {
43 private static final Logger LOG = LoggerFactory.getLogger(ServiceReferenceRegistryImpl.class);
45 private final Map<String, ModuleFactory> factories;
46 private final Map<String, Set<String>> factoryNamesToQNames;
47 // validator of incoming ObjectNames - throws InstanceNotFoundException if not found either in registry or transaction
48 private final LookupRegistry lookupRegistry;
49 private final ServiceReferenceRegistrator serviceReferenceRegistrator;
50 // helper method for getting QName of SI from namespace + local name
51 private final Map<String /* namespace */, Map<String /* local name */, ServiceInterfaceAnnotation>> namespacesToAnnotations;
52 private final Map<String /* service qName */, ServiceInterfaceAnnotation> serviceQNamesToAnnotations;
53 // all Service Interface qNames for sanity checking
54 private final Set<String /* qName */> allQNames;
55 Map<ModuleIdentifier, Map<ServiceInterfaceAnnotation, String /* service ref name */>> modulesToServiceRef = new HashMap<>();
58 // actual reference database
59 private final Map<ServiceReference, ModuleIdentifier> refNames = new HashMap<>();
60 private final boolean writable;
61 private final Map<ServiceReference, Entry<ServiceReferenceMXBeanImpl, ServiceReferenceJMXRegistration>> mBeans = new HashMap<>();
64 * Static constructor for config registry. Since only transaction can write to this registry, it will
67 public static CloseableServiceReferenceReadableRegistry createInitialSRLookupRegistry() {
68 // since this is initial state, just throw exception:
69 LookupRegistry lookupRegistry = new LookupRegistry() {
71 public Set<ObjectName> lookupConfigBeans() {
72 throw new UnsupportedOperationException();
76 public Set<ObjectName> lookupConfigBeans(final String moduleName) {
77 throw new UnsupportedOperationException();
81 public Set<ObjectName> lookupConfigBeans(final String moduleName, final String instanceName) {
82 throw new UnsupportedOperationException();
86 public ObjectName lookupConfigBean(final String moduleName, final String instanceName) throws InstanceNotFoundException {
87 throw new UnsupportedOperationException();
91 public void checkConfigBeanExists(final ObjectName objectName) throws InstanceNotFoundException {
92 throw new InstanceNotFoundException("Cannot find " + objectName + " - Tried to use mocking registry");
96 public Set<String> getAvailableModuleFactoryQNames() {
97 throw new UnsupportedOperationException();
101 public String toString() {
105 ServiceReferenceTransactionRegistratorFactory serviceReferenceRegistratorFactory = new ServiceReferenceTransactionRegistratorFactory(){
107 public ServiceReferenceRegistrator create() {
108 return new ServiceReferenceRegistrator() {
110 public String getNullableTransactionName() {
111 throw new UnsupportedOperationException();
115 public ServiceReferenceJMXRegistration registerMBean(final ServiceReferenceMXBeanImpl object, final ObjectName on) throws InstanceAlreadyExistsException {
116 throw new UnsupportedOperationException();
120 public void close() {
126 return new ServiceReferenceRegistryImpl(Collections.<String, ModuleFactory>emptyMap(), lookupRegistry,
127 serviceReferenceRegistratorFactory, false);
131 * Static constructor for transaction controller. Take current state as seen by config registry, allow writing new data.
133 public static SearchableServiceReferenceWritableRegistry createSRWritableRegistry(final ServiceReferenceReadableRegistry oldReadableRegistry,
134 final ConfigTransactionLookupRegistry txLookupRegistry,
135 final Map<String, Map.Entry<ModuleFactory, BundleContext>> currentlyRegisteredFactories) {
137 if (txLookupRegistry == null) {
138 throw new IllegalArgumentException("txLookupRegistry is null");
140 ServiceReferenceRegistryImpl old = (ServiceReferenceRegistryImpl) oldReadableRegistry;
141 Map<String, ModuleFactory> factories = extractFactoriesMap(currentlyRegisteredFactories);
142 ServiceReferenceTransactionRegistratorFactory serviceReferenceRegistratorFactory = new ServiceReferenceTransactionRegistratorFactoryImpl(
143 txLookupRegistry.getTxModuleJMXRegistrator(), txLookupRegistry.getTxModuleJMXRegistrator().getTransactionName());
144 ServiceReferenceRegistryImpl newRegistry = new ServiceReferenceRegistryImpl(factories, txLookupRegistry,
145 serviceReferenceRegistratorFactory, true);
146 copy(old, newRegistry, txLookupRegistry.getTransactionIdentifier().getName());
151 * Copy back state to config registry after commit.
153 public static CloseableServiceReferenceReadableRegistry createSRReadableRegistry(final ServiceReferenceWritableRegistry oldWritableRegistry,
154 final LookupRegistry lookupRegistry, final BaseJMXRegistrator baseJMXRegistrator) {
155 ServiceReferenceRegistryImpl old = (ServiceReferenceRegistryImpl) oldWritableRegistry;
157 // even if factories do change, nothing in the mapping can change between transactions
158 ServiceReferenceTransactionRegistratorFactory serviceReferenceRegistratorFactory = new ServiceReferenceTransactionRegistratorFactoryImpl(baseJMXRegistrator);
159 ServiceReferenceRegistryImpl newRegistry = new ServiceReferenceRegistryImpl(old.factories, lookupRegistry,
160 serviceReferenceRegistratorFactory, false);
161 copy(old, newRegistry, null);
166 * Fill refNames and mBeans maps from old instance
168 private static void copy(final ServiceReferenceRegistryImpl old, final ServiceReferenceRegistryImpl newRegistry, final String nullableDstTransactionName) {
169 for (Entry<ServiceReference, Entry<ServiceReferenceMXBeanImpl, ServiceReferenceJMXRegistration>> refNameEntry : old.mBeans.entrySet()) {
170 ObjectName currentImplementation;
171 ObjectName currentImplementationSrc = refNameEntry.getValue().getKey().getCurrentImplementation();
172 if (nullableDstTransactionName != null) {
173 currentImplementation = ObjectNameUtil.withTransactionName(currentImplementationSrc, nullableDstTransactionName);
175 currentImplementation = ObjectNameUtil.withoutTransactionName(currentImplementationSrc);
178 boolean skipChecks = true;
179 newRegistry.saveServiceReference(refNameEntry.getKey(), currentImplementation, skipChecks);
180 } catch (InstanceNotFoundException e) {
181 LOG.error("Cannot save service reference({}, {})", refNameEntry.getKey(), currentImplementation);
182 throw new IllegalStateException("Possible code error", e);
187 private static Map<String, ModuleFactory> extractFactoriesMap(final Map<String, Map.Entry<ModuleFactory, BundleContext>> currentlyRegisteredFactories) {
188 Map<String, ModuleFactory> result = new HashMap<>();
189 for (Entry<String, Entry<ModuleFactory, BundleContext>> entry : currentlyRegisteredFactories.entrySet()) {
190 result.put(entry.getKey(), entry.getValue().getKey());
195 private ServiceReferenceRegistryImpl(final Map<String, ModuleFactory> factories, final LookupRegistry lookupRegistry,
196 final ServiceReferenceTransactionRegistratorFactory serviceReferenceRegistratorFactory,
197 final boolean writable) {
198 this.factories = factories;
199 this.writable = writable;
200 this.lookupRegistry = lookupRegistry;
202 this.serviceReferenceRegistrator = serviceReferenceRegistratorFactory.create();
204 Map<String, Set<String /* QName */>> modifiableFactoryNamesToQNames = new HashMap<>();
205 Set<ServiceInterfaceAnnotation> allAnnotations = new HashSet<>();
206 Set<String /* qName */> allQNameSet = new HashSet<>();
209 for (Entry<String, ModuleFactory> entry : factories.entrySet()) {
210 if (entry.getKey().equals(entry.getValue().getImplementationName()) == false) {
211 LOG.error("Possible error in code: Mismatch between supplied and actual name of {}", entry);
212 throw new IllegalArgumentException("Possible error in code: Mismatch between supplied and actual name of " + entry);
214 Set<ServiceInterfaceAnnotation> siAnnotations = InterfacesHelper.getServiceInterfaceAnnotations(entry.getValue());
215 Set<String> qNames = InterfacesHelper.getQNames(siAnnotations);
216 allAnnotations.addAll(siAnnotations);
217 allQNameSet.addAll(qNames);
218 modifiableFactoryNamesToQNames.put(entry.getKey(), qNames);
220 this.factoryNamesToQNames = ImmutableMap.copyOf(modifiableFactoryNamesToQNames);
221 this.allQNames = ImmutableSet.copyOf(allQNameSet);
222 // fill namespacesToAnnotations
223 Map<String /* namespace */, Map<String /* localName */, ServiceInterfaceAnnotation>> modifiableNamespacesToAnnotations =
225 Map<String /* service qName*/, ServiceInterfaceAnnotation> modifiableServiceQNamesToAnnotations = new HashMap<>();
226 for (ServiceInterfaceAnnotation sia : allAnnotations) {
227 Map<String, ServiceInterfaceAnnotation> ofNamespace = modifiableNamespacesToAnnotations.get(sia.namespace());
228 if (ofNamespace == null) {
229 ofNamespace = new HashMap<>();
230 modifiableNamespacesToAnnotations.put(sia.namespace(), ofNamespace);
232 if (ofNamespace.containsKey(sia.localName())) {
233 LOG.error("Cannot construct namespacesToAnnotations map, conflict between local names in {}, offending local name: {}, map so far {}",
234 sia.namespace(), sia.localName(), modifiableNamespacesToAnnotations);
235 throw new IllegalArgumentException("Conflict between local names in " + sia.namespace() + " : " + sia.localName());
237 ofNamespace.put(sia.localName(), sia);
238 modifiableServiceQNamesToAnnotations.put(sia.value(), sia);
240 this.namespacesToAnnotations = ImmutableMap.copyOf(modifiableNamespacesToAnnotations);
241 this.serviceQNamesToAnnotations = ImmutableMap.copyOf(modifiableServiceQNamesToAnnotations);
242 LOG.trace("factoryNamesToQNames:{}", this.factoryNamesToQNames);
246 public Map<ServiceInterfaceAnnotation, String /* service ref name */> findServiceInterfaces(final ModuleIdentifier moduleIdentifier) {
247 Map<ServiceInterfaceAnnotation, String /* service ref name */> result = modulesToServiceRef.get(moduleIdentifier);
248 if (result == null) {
249 return Collections.emptyMap();
251 return Collections.unmodifiableMap(result);
255 public synchronized Set<String> lookupServiceInterfaceNames(final ObjectName objectName) throws InstanceNotFoundException {
256 lookupRegistry.checkConfigBeanExists(objectName);
258 String factoryName = ObjectNameUtil.getFactoryName(objectName);
259 Set<String> serviceInterfaceAnnotations = factoryNamesToQNames.get(factoryName);
260 if (serviceInterfaceAnnotations == null) {
261 LOG.error("Possible error in code: cannot find factory annotations of '{}' extracted from ON {} in {}",
262 factoryName, objectName, factoryNamesToQNames);
263 throw new IllegalArgumentException("Cannot find factory with name " + factoryName);
265 return serviceInterfaceAnnotations;
269 public synchronized String getServiceInterfaceName(final String namespace, final String localName) {
270 Map<String /* localName */, ServiceInterfaceAnnotation> ofNamespace = namespacesToAnnotations.get(namespace);
271 if (ofNamespace == null) {
272 LOG.error("Cannot find namespace {} in {}", namespace, namespacesToAnnotations);
273 throw new IllegalArgumentException("Cannot find namespace " + namespace);
275 ServiceInterfaceAnnotation sia = ofNamespace.get(localName);
277 LOG.error("Cannot find local name {} in namespace {}, found only {}", localName, namespace, ofNamespace);
278 throw new IllegalArgumentException("Cannot find local name " + localName + " in namespace " + namespace);
286 public synchronized Map<String /* serviceInterfaceName */, Map<String/* refName */, ObjectName>> getServiceMapping() {
287 Map<String /* serviceInterfaceName */, Map<String/* refName */, ObjectName>> result = new HashMap<>();
288 for (Entry<ServiceReference, ModuleIdentifier> entry: refNames.entrySet()) {
289 String qName = entry.getKey().getServiceInterfaceQName();
290 Map<String /* refName */, ObjectName> innerMap = result.get(qName);
291 if (innerMap == null) {
292 innerMap = new HashMap<>();
293 result.put(qName, innerMap);
295 innerMap.put(entry.getKey().getRefName(), getObjectName(entry.getValue()));
300 private ObjectName getObjectName(final ModuleIdentifier moduleIdentifier) {
303 on = lookupRegistry.lookupConfigBean(moduleIdentifier.getFactoryName(), moduleIdentifier.getInstanceName());
304 } catch (InstanceNotFoundException e) {
305 LOG.error("Cannot find instance {}", moduleIdentifier);
306 throw new IllegalStateException("Cannot find instance " + moduleIdentifier, e);
312 public synchronized ObjectName lookupConfigBeanByServiceInterfaceName(final String serviceInterfaceQName, final String refName) {
313 ServiceReference serviceReference = new ServiceReference(serviceInterfaceQName, refName);
314 ModuleIdentifier moduleIdentifier = refNames.get(serviceReference);
315 if (moduleIdentifier == null) {
316 LOG.error("Cannot find qname {} and refName {} in {}", serviceInterfaceQName, refName, refName);
317 throw new IllegalArgumentException("Cannot find " + serviceReference);
319 return getObjectName(moduleIdentifier);
323 public synchronized Map<String /* refName */, ObjectName> lookupServiceReferencesByServiceInterfaceName(final String serviceInterfaceQName) {
324 Map<String, Map<String, ObjectName>> serviceMapping = getServiceMapping();
325 Map<String, ObjectName> innerMap = serviceMapping.get(serviceInterfaceQName);
326 if (innerMap == null) {
327 LOG.error("Cannot find qname {} in {}", serviceInterfaceQName, refNames);
328 throw new IllegalArgumentException("Cannot find " + serviceInterfaceQName);
334 public synchronized ObjectName getServiceReference(final String serviceInterfaceQName, final String refName) throws InstanceNotFoundException {
335 ServiceReference serviceReference = new ServiceReference(serviceInterfaceQName, refName);
336 if (mBeans.containsKey(serviceReference) == false) {
337 throw new InstanceNotFoundException("Cannot find " + serviceReference);
339 return getServiceON(serviceReference);
343 public synchronized void checkServiceReferenceExists(final ObjectName objectName) throws InstanceNotFoundException {
344 String actualTransactionName = ObjectNameUtil.getTransactionName(objectName);
345 String expectedTransactionName = serviceReferenceRegistrator.getNullableTransactionName();
346 if (writable & actualTransactionName == null || (writable && actualTransactionName.equals(expectedTransactionName) == false)) {
347 throw new IllegalArgumentException("Mismatched transaction name in " + objectName);
349 String serviceQName = ObjectNameUtil.getServiceQName(objectName);
350 String referenceName = ObjectNameUtil.getReferenceName(objectName);
351 ServiceReference serviceReference = new ServiceReference(serviceQName, referenceName);
352 if (refNames.containsKey(serviceReference) == false) {
353 LOG.warn("Cannot find {} in {}", serviceReference, refNames);
354 throw new InstanceNotFoundException("Service reference not found:" + objectName);
360 private void assertWritable() {
361 if (writable == false) {
362 throw new IllegalStateException("Cannot write to readable registry");
367 public synchronized ObjectName saveServiceReference(final String serviceInterfaceName, final String refName, final ObjectName moduleON) throws InstanceNotFoundException {
369 ServiceReference serviceReference = new ServiceReference(serviceInterfaceName, refName);
370 return saveServiceReference(serviceReference, moduleON);
373 private synchronized ObjectName saveServiceReference(final ServiceReference serviceReference, final ObjectName moduleON)
374 throws InstanceNotFoundException{
375 return saveServiceReference(serviceReference, moduleON, false);
378 private synchronized ObjectName saveServiceReference(final ServiceReference serviceReference, final ObjectName moduleON,
379 final boolean skipChecks) throws InstanceNotFoundException {
381 // make sure it is found
382 if (skipChecks == false) {
383 lookupRegistry.checkConfigBeanExists(moduleON);
385 String factoryName = ObjectNameUtil.getFactoryName(moduleON);
386 String instanceName = ObjectNameUtil.getInstanceName(moduleON);
387 ModuleIdentifier moduleIdentifier = new ModuleIdentifier(factoryName, instanceName);
389 // check that service interface name exist
390 Set<String> serviceInterfaceQNames = factoryNamesToQNames.get(moduleIdentifier.getFactoryName());
391 if (serviceInterfaceQNames == null) {
392 LOG.error("Possible error in code: cannot find factoryName {} in {}, {}", moduleIdentifier.getFactoryName(),
393 factoryNamesToQNames, moduleIdentifier);
394 throw new IllegalStateException("Possible error in code: cannot find annotations of existing factory " + moduleIdentifier.getFactoryName());
396 // supplied serviceInterfaceName must exist in this collection
397 if (serviceInterfaceQNames.contains(serviceReference.getServiceInterfaceQName()) == false) {
398 LOG.error("Cannot find qName {} with factory name {}, found {}", serviceReference.getServiceInterfaceQName(), moduleIdentifier.getFactoryName(), serviceInterfaceQNames);
399 throw new IllegalArgumentException("Cannot find service interface " + serviceReference.getServiceInterfaceQName() + " within factory " + moduleIdentifier.getFactoryName());
403 // create service reference object name, put to mBeans
404 ObjectName result = getServiceON(serviceReference);
405 Entry<ServiceReferenceMXBeanImpl, ServiceReferenceJMXRegistration> mxBeanEntry = mBeans.get(serviceReference);
406 if (mxBeanEntry == null) {
407 // create dummy mx bean
408 ServiceReferenceMXBeanImpl dummyMXBean = new ServiceReferenceMXBeanImpl(moduleON);
409 ServiceReferenceJMXRegistration dummyMXBeanRegistration;
411 dummyMXBeanRegistration = serviceReferenceRegistrator.registerMBean(dummyMXBean, result);
412 } catch (InstanceAlreadyExistsException e) {
413 throw new IllegalStateException("Possible error in code. Cannot register " + result, e);
415 mBeans.put(serviceReference, createMXBeanEntry(dummyMXBean, dummyMXBeanRegistration));
418 mxBeanEntry.getKey().setCurrentImplementation(moduleON);
421 refNames.put(serviceReference, moduleIdentifier);
422 Map<ServiceInterfaceAnnotation, String /* service ref name */> refNamesToAnnotations = modulesToServiceRef.get(moduleIdentifier);
423 if (refNamesToAnnotations == null){
424 refNamesToAnnotations = new HashMap<>();
425 modulesToServiceRef.put(moduleIdentifier, refNamesToAnnotations);
428 ServiceInterfaceAnnotation annotation = serviceQNamesToAnnotations.get(serviceReference.getServiceInterfaceQName());
429 checkNotNull(annotation, "Possible error in code, cannot find annotation for " + serviceReference);
430 refNamesToAnnotations.put(annotation, serviceReference.getRefName());
434 private Entry<ServiceReferenceMXBeanImpl, ServiceReferenceJMXRegistration> createMXBeanEntry(
435 final ServiceReferenceMXBeanImpl mxBean, final ServiceReferenceJMXRegistration registration) {
436 return new Entry<ServiceReferenceMXBeanImpl, ServiceReferenceJMXRegistration>() {
438 public ServiceReferenceMXBeanImpl getKey() {
443 public ServiceReferenceJMXRegistration getValue() {
448 public ServiceReferenceJMXRegistration setValue(final ServiceReferenceJMXRegistration value) {
449 throw new UnsupportedOperationException();
454 private ObjectName getServiceON(final ServiceReference serviceReference) {
456 return ObjectNameUtil.createTransactionServiceON(serviceReferenceRegistrator.getNullableTransactionName(),
457 serviceReference.getServiceInterfaceQName(), serviceReference.getRefName());
459 return ObjectNameUtil.createReadOnlyServiceON(serviceReference.getServiceInterfaceQName(), serviceReference.getRefName());
464 public synchronized void removeServiceReference(final String serviceInterfaceName, final String refName) throws InstanceNotFoundException{
465 ServiceReference serviceReference = new ServiceReference(serviceInterfaceName, refName);
466 removeServiceReference(serviceReference);
469 private synchronized void removeServiceReference(final ServiceReference serviceReference) throws InstanceNotFoundException {
470 LOG.debug("Removing service reference {} from {}", serviceReference, this);
472 // is the qName known?
473 if (allQNames.contains(serviceReference.getServiceInterfaceQName()) == false) {
474 LOG.error("Cannot find qname {} in {}", serviceReference.getServiceInterfaceQName(), allQNames);
475 throw new IllegalArgumentException("Cannot find service interface " + serviceReference.getServiceInterfaceQName());
477 ModuleIdentifier removed = refNames.remove(serviceReference);
478 if (removed == null){
479 throw new InstanceNotFoundException("Cannot find " + serviceReference.getServiceInterfaceQName());
481 Entry<ServiceReferenceMXBeanImpl, ServiceReferenceJMXRegistration> entry = mBeans.remove(serviceReference);
483 throw new IllegalStateException("Possible code error: cannot remove from mBeans: " + serviceReference);
485 entry.getValue().close();
489 public synchronized void removeAllServiceReferences() {
491 for (ServiceReference serviceReference: mBeans.keySet()) {
493 removeServiceReference(serviceReference);
494 } catch (InstanceNotFoundException e) {
495 throw new IllegalStateException("Possible error in code", e);
501 public synchronized boolean removeServiceReferences(final ObjectName moduleObjectName) throws InstanceNotFoundException {
502 lookupRegistry.checkConfigBeanExists(moduleObjectName);
503 String factoryName = ObjectNameUtil.getFactoryName(moduleObjectName);
504 // check that service interface name exist
505 Set<String> serviceInterfaceQNames = factoryNamesToQNames.get(factoryName);
506 return removeServiceReferences(moduleObjectName, serviceInterfaceQNames);
510 private boolean removeServiceReferences(final ObjectName moduleObjectName, final Set<String> qNames) throws InstanceNotFoundException {
511 ObjectNameUtil.checkType(moduleObjectName, ObjectNameUtil.TYPE_MODULE);
513 Set<ServiceReference> serviceReferencesLinkingTo = findServiceReferencesLinkingTo(moduleObjectName, qNames);
514 for (ServiceReference sr : serviceReferencesLinkingTo) {
515 removeServiceReference(sr);
517 return serviceReferencesLinkingTo.isEmpty() == false;
520 private Set<ServiceReference> findServiceReferencesLinkingTo(final ObjectName moduleObjectName, final Set<String> serviceInterfaceQNames) {
521 String factoryName = ObjectNameUtil.getFactoryName(moduleObjectName);
522 if (serviceInterfaceQNames == null) {
523 LOG.warn("Possible error in code: cannot find factoryName {} in {}, object name {}", factoryName, factoryNamesToQNames, moduleObjectName);
524 throw new IllegalStateException("Possible error in code: cannot find annotations of existing factory " + factoryName);
526 String instanceName = ObjectNameUtil.getInstanceName(moduleObjectName);
527 ModuleIdentifier moduleIdentifier = new ModuleIdentifier(factoryName, instanceName);
528 Set<ServiceReference> result = new HashSet<>();
529 for (Entry<ServiceReference, ModuleIdentifier> entry : refNames.entrySet()) {
530 if (entry.getValue().equals(moduleIdentifier)) {
531 result.add(entry.getKey());
538 public String toString() {
539 return "ServiceReferenceRegistryImpl{" +
540 "lookupRegistry=" + lookupRegistry +
541 "refNames=" + refNames +
542 ", factoryNamesToQNames=" + factoryNamesToQNames +
547 public void close() {
548 serviceReferenceRegistrator.close();