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;
11 import com.google.common.collect.ImmutableMap;
12 import com.google.common.collect.ImmutableSet;
13 import java.util.Collections;
14 import java.util.HashMap;
15 import java.util.HashSet;
17 import java.util.Map.Entry;
19 import javax.management.InstanceAlreadyExistsException;
20 import javax.management.InstanceNotFoundException;
21 import javax.management.ObjectName;
22 import org.opendaylight.controller.config.api.LookupRegistry;
23 import org.opendaylight.controller.config.api.ModuleIdentifier;
24 import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
25 import org.opendaylight.controller.config.api.ServiceReferenceWritableRegistry;
26 import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation;
27 import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
28 import org.opendaylight.controller.config.manager.impl.jmx.BaseJMXRegistrator;
29 import org.opendaylight.controller.config.manager.impl.jmx.ServiceReference;
30 import org.opendaylight.controller.config.manager.impl.jmx.ServiceReferenceMXBeanImpl;
31 import org.opendaylight.controller.config.manager.impl.jmx.ServiceReferenceRegistrator;
32 import org.opendaylight.controller.config.manager.impl.jmx.ServiceReferenceRegistrator.ServiceReferenceJMXRegistration;
33 import org.opendaylight.controller.config.manager.impl.jmx.ServiceReferenceRegistrator.ServiceReferenceTransactionRegistratorFactory;
34 import org.opendaylight.controller.config.manager.impl.jmx.ServiceReferenceRegistrator.ServiceReferenceTransactionRegistratorFactoryImpl;
35 import org.opendaylight.controller.config.manager.impl.util.InterfacesHelper;
36 import org.opendaylight.controller.config.spi.ModuleFactory;
37 import org.osgi.framework.BundleContext;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
41 public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceReadableRegistry, SearchableServiceReferenceWritableRegistry {
42 private static final Logger LOGGER = LoggerFactory.getLogger(ServiceReferenceRegistryImpl.class);
44 private final Map<String, ModuleFactory> factories;
45 private final Map<String, Set<String>> factoryNamesToQNames;
46 // validator of incoming ObjectNames - throws InstanceNotFoundException if not found either in registry or transaction
47 private final LookupRegistry lookupRegistry;
48 private final ServiceReferenceRegistrator serviceReferenceRegistrator;
49 // helper method for getting QName of SI from namespace + local name
50 private final Map<String /* namespace */, Map<String /* local name */, ServiceInterfaceAnnotation>> namespacesToAnnotations;
51 private final Map<String /* service qName */, ServiceInterfaceAnnotation> serviceQNamesToAnnotations;
52 // all Service Interface qNames for sanity checking
53 private final Set<String /* qName */> allQNames;
54 Map<ModuleIdentifier, Map<ServiceInterfaceAnnotation, String /* service ref name */>> modulesToServiceRef = new HashMap<>();
57 // actual reference database
58 private final Map<ServiceReference, ModuleIdentifier> refNames = new HashMap<>();
59 private final boolean writable;
60 private final Map<ServiceReference, Entry<ServiceReferenceMXBeanImpl, ServiceReferenceJMXRegistration>> mBeans = new HashMap<>();
63 * Static constructor for config registry. Since only transaction can write to this registry, it will
66 public static CloseableServiceReferenceReadableRegistry createInitialSRLookupRegistry() {
67 // since this is initial state, just throw exception:
68 LookupRegistry lookupRegistry = new LookupRegistry() {
70 public Set<ObjectName> lookupConfigBeans() {
71 throw new UnsupportedOperationException();
75 public Set<ObjectName> lookupConfigBeans(final String moduleName) {
76 throw new UnsupportedOperationException();
80 public Set<ObjectName> lookupConfigBeans(final String moduleName, final String instanceName) {
81 throw new UnsupportedOperationException();
85 public ObjectName lookupConfigBean(final String moduleName, final String instanceName) throws InstanceNotFoundException {
86 throw new UnsupportedOperationException();
90 public void checkConfigBeanExists(final ObjectName objectName) throws InstanceNotFoundException {
91 throw new InstanceNotFoundException("Cannot find " + objectName + " - Tried to use mocking registry");
95 public Set<String> getAvailableModuleFactoryQNames() {
96 throw new UnsupportedOperationException();
100 public String toString() {
104 ServiceReferenceTransactionRegistratorFactory serviceReferenceRegistratorFactory = new ServiceReferenceTransactionRegistratorFactory(){
106 public ServiceReferenceRegistrator create() {
107 return new ServiceReferenceRegistrator() {
109 public String getNullableTransactionName() {
110 throw new UnsupportedOperationException();
114 public ServiceReferenceJMXRegistration registerMBean(final ServiceReferenceMXBeanImpl object, final ObjectName on) throws InstanceAlreadyExistsException {
115 throw new UnsupportedOperationException();
119 public void close() {
125 return new ServiceReferenceRegistryImpl(Collections.<String, ModuleFactory>emptyMap(), lookupRegistry,
126 serviceReferenceRegistratorFactory, false);
130 * Static constructor for transaction controller. Take current state as seen by config registry, allow writing new data.
132 public static SearchableServiceReferenceWritableRegistry createSRWritableRegistry(final ServiceReferenceReadableRegistry oldReadableRegistry,
133 final ConfigTransactionLookupRegistry txLookupRegistry,
134 final Map<String, Map.Entry<ModuleFactory, BundleContext>> currentlyRegisteredFactories) {
136 if (txLookupRegistry == null) {
137 throw new IllegalArgumentException("txLookupRegistry is null");
139 ServiceReferenceRegistryImpl old = (ServiceReferenceRegistryImpl) oldReadableRegistry;
140 Map<String, ModuleFactory> factories = extractFactoriesMap(currentlyRegisteredFactories);
141 ServiceReferenceTransactionRegistratorFactory serviceReferenceRegistratorFactory = new ServiceReferenceTransactionRegistratorFactoryImpl(
142 txLookupRegistry.getTxModuleJMXRegistrator(), txLookupRegistry.getTxModuleJMXRegistrator().getTransactionName());
143 ServiceReferenceRegistryImpl newRegistry = new ServiceReferenceRegistryImpl(factories, txLookupRegistry,
144 serviceReferenceRegistratorFactory, true);
145 copy(old, newRegistry, txLookupRegistry.getTransactionIdentifier().getName());
150 * Copy back state to config registry after commit.
152 public static CloseableServiceReferenceReadableRegistry createSRReadableRegistry(final ServiceReferenceWritableRegistry oldWritableRegistry,
153 final LookupRegistry lookupRegistry, final BaseJMXRegistrator baseJMXRegistrator) {
154 ServiceReferenceRegistryImpl old = (ServiceReferenceRegistryImpl) oldWritableRegistry;
156 // even if factories do change, nothing in the mapping can change between transactions
157 ServiceReferenceTransactionRegistratorFactory serviceReferenceRegistratorFactory = new ServiceReferenceTransactionRegistratorFactoryImpl(baseJMXRegistrator);
158 ServiceReferenceRegistryImpl newRegistry = new ServiceReferenceRegistryImpl(old.factories, lookupRegistry,
159 serviceReferenceRegistratorFactory, false);
160 copy(old, newRegistry, null);
165 * Fill refNames and mBeans maps from old instance
167 private static void copy(final ServiceReferenceRegistryImpl old, final ServiceReferenceRegistryImpl newRegistry, final String nullableDstTransactionName) {
168 for (Entry<ServiceReference, Entry<ServiceReferenceMXBeanImpl, ServiceReferenceJMXRegistration>> refNameEntry : old.mBeans.entrySet()) {
169 ObjectName currentImplementation;
170 ObjectName currentImplementationSrc = refNameEntry.getValue().getKey().getCurrentImplementation();
171 if (nullableDstTransactionName != null) {
172 currentImplementation = ObjectNameUtil.withTransactionName(currentImplementationSrc, nullableDstTransactionName);
174 currentImplementation = ObjectNameUtil.withoutTransactionName(currentImplementationSrc);
177 boolean skipChecks = true;
178 newRegistry.saveServiceReference(refNameEntry.getKey(), currentImplementation, skipChecks);
179 } catch (InstanceNotFoundException e) {
180 LOGGER.error("Cannot save service reference({}, {})", refNameEntry.getKey(), currentImplementation);
181 throw new IllegalStateException("Possible code error", e);
186 private static Map<String, ModuleFactory> extractFactoriesMap(final Map<String, Map.Entry<ModuleFactory, BundleContext>> currentlyRegisteredFactories) {
187 Map<String, ModuleFactory> result = new HashMap<>();
188 for (Entry<String, Entry<ModuleFactory, BundleContext>> entry : currentlyRegisteredFactories.entrySet()) {
189 result.put(entry.getKey(), entry.getValue().getKey());
194 private ServiceReferenceRegistryImpl(final Map<String, ModuleFactory> factories, final LookupRegistry lookupRegistry,
195 final ServiceReferenceTransactionRegistratorFactory serviceReferenceRegistratorFactory,
196 final boolean writable) {
197 this.factories = factories;
198 this.writable = writable;
199 this.lookupRegistry = lookupRegistry;
201 this.serviceReferenceRegistrator = serviceReferenceRegistratorFactory.create();
203 Map<String, Set<String /* QName */>> modifiableFactoryNamesToQNames = new HashMap<>();
204 Set<ServiceInterfaceAnnotation> allAnnotations = new HashSet<>();
205 Set<String /* qName */> allQNameSet = new HashSet<>();
208 for (Entry<String, ModuleFactory> entry : factories.entrySet()) {
209 if (entry.getKey().equals(entry.getValue().getImplementationName()) == false) {
210 LOGGER.error("Possible error in code: Mismatch between supplied and actual name of {}", entry);
211 throw new IllegalArgumentException("Possible error in code: Mismatch between supplied and actual name of " + entry);
213 Set<ServiceInterfaceAnnotation> siAnnotations = InterfacesHelper.getServiceInterfaceAnnotations(entry.getValue());
214 Set<String> qNames = InterfacesHelper.getQNames(siAnnotations);
215 allAnnotations.addAll(siAnnotations);
216 allQNameSet.addAll(qNames);
217 modifiableFactoryNamesToQNames.put(entry.getKey(), qNames);
219 this.factoryNamesToQNames = ImmutableMap.copyOf(modifiableFactoryNamesToQNames);
220 this.allQNames = ImmutableSet.copyOf(allQNameSet);
221 // fill namespacesToAnnotations
222 Map<String /* namespace */, Map<String /* localName */, ServiceInterfaceAnnotation>> modifiableNamespacesToAnnotations =
224 Map<String /* service qName*/, ServiceInterfaceAnnotation> modifiableServiceQNamesToAnnotations = new HashMap<>();
225 for (ServiceInterfaceAnnotation sia : allAnnotations) {
226 Map<String, ServiceInterfaceAnnotation> ofNamespace = modifiableNamespacesToAnnotations.get(sia.namespace());
227 if (ofNamespace == null) {
228 ofNamespace = new HashMap<>();
229 modifiableNamespacesToAnnotations.put(sia.namespace(), ofNamespace);
231 if (ofNamespace.containsKey(sia.localName())) {
232 LOGGER.error("Cannot construct namespacesToAnnotations map, conflict between local names in {}, offending local name: {}, map so far {}",
233 sia.namespace(), sia.localName(), modifiableNamespacesToAnnotations);
234 throw new IllegalArgumentException("Conflict between local names in " + sia.namespace() + " : " + sia.localName());
236 ofNamespace.put(sia.localName(), sia);
237 modifiableServiceQNamesToAnnotations.put(sia.value(), sia);
239 this.namespacesToAnnotations = ImmutableMap.copyOf(modifiableNamespacesToAnnotations);
240 this.serviceQNamesToAnnotations = ImmutableMap.copyOf(modifiableServiceQNamesToAnnotations);
241 LOGGER.trace("factoryNamesToQNames:{}", this.factoryNamesToQNames);
245 public Map<ServiceInterfaceAnnotation, String /* service ref name */> findServiceInterfaces(final ModuleIdentifier moduleIdentifier) {
246 Map<ServiceInterfaceAnnotation, String /* service ref name */> result = modulesToServiceRef.get(moduleIdentifier);
247 if (result == null) {
248 return Collections.emptyMap();
250 return Collections.unmodifiableMap(result);
254 public synchronized Set<String> lookupServiceInterfaceNames(final ObjectName objectName) throws InstanceNotFoundException {
255 lookupRegistry.checkConfigBeanExists(objectName);
257 String factoryName = ObjectNameUtil.getFactoryName(objectName);
258 Set<String> serviceInterfaceAnnotations = factoryNamesToQNames.get(factoryName);
259 if (serviceInterfaceAnnotations == null) {
260 LOGGER.error("Possible error in code: cannot find factory annotations of '{}' extracted from ON {} in {}",
261 factoryName, objectName, factoryNamesToQNames);
262 throw new IllegalArgumentException("Cannot find factory with name " + factoryName);
264 return serviceInterfaceAnnotations;
268 public synchronized String getServiceInterfaceName(final String namespace, final String localName) {
269 Map<String /* localName */, ServiceInterfaceAnnotation> ofNamespace = namespacesToAnnotations.get(namespace);
270 if (ofNamespace == null) {
271 LOGGER.error("Cannot find namespace {} in {}", namespace, namespacesToAnnotations);
272 throw new IllegalArgumentException("Cannot find namespace " + namespace);
274 ServiceInterfaceAnnotation sia = ofNamespace.get(localName);
276 LOGGER.error("Cannot find local name {} in namespace {}, found only {}", localName, namespace, ofNamespace);
277 throw new IllegalArgumentException("Cannot find local name " + localName + " in namespace " + namespace);
285 public synchronized Map<String /* serviceInterfaceName */, Map<String/* refName */, ObjectName>> getServiceMapping() {
286 Map<String /* serviceInterfaceName */, Map<String/* refName */, ObjectName>> result = new HashMap<>();
287 for (Entry<ServiceReference, ModuleIdentifier> entry: refNames.entrySet()) {
288 String qName = entry.getKey().getServiceInterfaceQName();
289 Map<String /* refName */, ObjectName> innerMap = result.get(qName);
290 if (innerMap == null) {
291 innerMap = new HashMap<>();
292 result.put(qName, innerMap);
294 innerMap.put(entry.getKey().getRefName(), getObjectName(entry.getValue()));
299 private ObjectName getObjectName(final ModuleIdentifier moduleIdentifier) {
302 on = lookupRegistry.lookupConfigBean(moduleIdentifier.getFactoryName(), moduleIdentifier.getInstanceName());
303 } catch (InstanceNotFoundException e) {
304 LOGGER.error("Cannot find instance {}", moduleIdentifier);
305 throw new IllegalStateException("Cannot find instance " + moduleIdentifier, e);
311 public synchronized ObjectName lookupConfigBeanByServiceInterfaceName(final String serviceInterfaceQName, final String refName) {
312 ServiceReference serviceReference = new ServiceReference(serviceInterfaceQName, refName);
313 ModuleIdentifier moduleIdentifier = refNames.get(serviceReference);
314 if (moduleIdentifier == null) {
315 LOGGER.error("Cannot find qname {} and refName {} in {}", serviceInterfaceQName, refName, refName);
316 throw new IllegalArgumentException("Cannot find " + serviceReference);
318 return getObjectName(moduleIdentifier);
322 public synchronized Map<String /* refName */, ObjectName> lookupServiceReferencesByServiceInterfaceName(final String serviceInterfaceQName) {
323 Map<String, Map<String, ObjectName>> serviceMapping = getServiceMapping();
324 Map<String, ObjectName> innerMap = serviceMapping.get(serviceInterfaceQName);
325 if (innerMap == null) {
326 LOGGER.error("Cannot find qname {} in {}", serviceInterfaceQName, refNames);
327 throw new IllegalArgumentException("Cannot find " + serviceInterfaceQName);
333 public synchronized ObjectName getServiceReference(final String serviceInterfaceQName, final String refName) throws InstanceNotFoundException {
334 ServiceReference serviceReference = new ServiceReference(serviceInterfaceQName, refName);
335 if (mBeans.containsKey(serviceReference) == false) {
336 throw new InstanceNotFoundException("Cannot find " + serviceReference);
338 return getServiceON(serviceReference);
342 public synchronized void checkServiceReferenceExists(final ObjectName objectName) throws InstanceNotFoundException {
343 String actualTransactionName = ObjectNameUtil.getTransactionName(objectName);
344 String expectedTransactionName = serviceReferenceRegistrator.getNullableTransactionName();
345 if (writable & actualTransactionName == null || (writable && actualTransactionName.equals(expectedTransactionName) == false)) {
346 throw new IllegalArgumentException("Mismatched transaction name in " + objectName);
348 String serviceQName = ObjectNameUtil.getServiceQName(objectName);
349 String referenceName = ObjectNameUtil.getReferenceName(objectName);
350 ServiceReference serviceReference = new ServiceReference(serviceQName, referenceName);
351 if (refNames.containsKey(serviceReference) == false) {
352 LOGGER.warn("Cannot find {} in {}", serviceReference, refNames);
353 throw new InstanceNotFoundException("Service reference not found:" + objectName);
359 private void assertWritable() {
360 if (writable == false) {
361 throw new IllegalStateException("Cannot write to readable registry");
366 public synchronized ObjectName saveServiceReference(final String serviceInterfaceName, final String refName, final ObjectName moduleON) throws InstanceNotFoundException {
368 ServiceReference serviceReference = new ServiceReference(serviceInterfaceName, refName);
369 return saveServiceReference(serviceReference, moduleON);
372 private synchronized ObjectName saveServiceReference(final ServiceReference serviceReference, final ObjectName moduleON)
373 throws InstanceNotFoundException{
374 return saveServiceReference(serviceReference, moduleON, false);
377 private synchronized ObjectName saveServiceReference(final ServiceReference serviceReference, final ObjectName moduleON,
378 final boolean skipChecks) throws InstanceNotFoundException {
380 // make sure it is found
381 if (skipChecks == false) {
382 lookupRegistry.checkConfigBeanExists(moduleON);
384 String factoryName = ObjectNameUtil.getFactoryName(moduleON);
385 String instanceName = ObjectNameUtil.getInstanceName(moduleON);
386 ModuleIdentifier moduleIdentifier = new ModuleIdentifier(factoryName, instanceName);
388 // check that service interface name exist
389 Set<String> serviceInterfaceQNames = factoryNamesToQNames.get(moduleIdentifier.getFactoryName());
390 if (serviceInterfaceQNames == null) {
391 LOGGER.error("Possible error in code: cannot find factoryName {} in {}, {}", moduleIdentifier.getFactoryName(),
392 factoryNamesToQNames, moduleIdentifier);
393 throw new IllegalStateException("Possible error in code: cannot find annotations of existing factory " + moduleIdentifier.getFactoryName());
395 // supplied serviceInterfaceName must exist in this collection
396 if (serviceInterfaceQNames.contains(serviceReference.getServiceInterfaceQName()) == false) {
397 LOGGER.error("Cannot find qName {} with factory name {}, found {}", serviceReference.getServiceInterfaceQName(), moduleIdentifier.getFactoryName(), serviceInterfaceQNames);
398 throw new IllegalArgumentException("Cannot find service interface " + serviceReference.getServiceInterfaceQName() + " within factory " + moduleIdentifier.getFactoryName());
402 // create service reference object name, put to mBeans
403 ObjectName result = getServiceON(serviceReference);
404 Entry<ServiceReferenceMXBeanImpl, ServiceReferenceJMXRegistration> mxBeanEntry = mBeans.get(serviceReference);
405 if (mxBeanEntry == null) {
406 // create dummy mx bean
407 ServiceReferenceMXBeanImpl dummyMXBean = new ServiceReferenceMXBeanImpl(moduleON);
408 ServiceReferenceJMXRegistration dummyMXBeanRegistration;
410 dummyMXBeanRegistration = serviceReferenceRegistrator.registerMBean(dummyMXBean, result);
411 } catch (InstanceAlreadyExistsException e) {
412 throw new IllegalStateException("Possible error in code. Cannot register " + result, e);
414 mBeans.put(serviceReference, createMXBeanEntry(dummyMXBean, dummyMXBeanRegistration));
417 mxBeanEntry.getKey().setCurrentImplementation(moduleON);
420 refNames.put(serviceReference, moduleIdentifier);
421 Map<ServiceInterfaceAnnotation, String /* service ref name */> refNamesToAnnotations = modulesToServiceRef.get(moduleIdentifier);
422 if (refNamesToAnnotations == null){
423 refNamesToAnnotations = new HashMap<>();
424 modulesToServiceRef.put(moduleIdentifier, refNamesToAnnotations);
427 ServiceInterfaceAnnotation annotation = serviceQNamesToAnnotations.get(serviceReference.getServiceInterfaceQName());
428 checkNotNull(annotation, "Possible error in code, cannot find annotation for " + serviceReference);
429 refNamesToAnnotations.put(annotation, serviceReference.getRefName());
433 private Entry<ServiceReferenceMXBeanImpl, ServiceReferenceJMXRegistration> createMXBeanEntry(
434 final ServiceReferenceMXBeanImpl mxBean, final ServiceReferenceJMXRegistration registration) {
435 return new Entry<ServiceReferenceMXBeanImpl, ServiceReferenceJMXRegistration>() {
437 public ServiceReferenceMXBeanImpl getKey() {
442 public ServiceReferenceJMXRegistration getValue() {
447 public ServiceReferenceJMXRegistration setValue(final ServiceReferenceJMXRegistration value) {
448 throw new UnsupportedOperationException();
453 private ObjectName getServiceON(final ServiceReference serviceReference) {
455 return ObjectNameUtil.createTransactionServiceON(serviceReferenceRegistrator.getNullableTransactionName(),
456 serviceReference.getServiceInterfaceQName(), serviceReference.getRefName());
458 return ObjectNameUtil.createReadOnlyServiceON(serviceReference.getServiceInterfaceQName(), serviceReference.getRefName());
463 public synchronized void removeServiceReference(final String serviceInterfaceName, final String refName) throws InstanceNotFoundException{
464 ServiceReference serviceReference = new ServiceReference(serviceInterfaceName, refName);
465 removeServiceReference(serviceReference);
468 private synchronized void removeServiceReference(final ServiceReference serviceReference) throws InstanceNotFoundException {
469 LOGGER.debug("Removing service reference {} from {}", serviceReference, this);
471 // is the qName known?
472 if (allQNames.contains(serviceReference.getServiceInterfaceQName()) == false) {
473 LOGGER.error("Cannot find qname {} in {}", serviceReference.getServiceInterfaceQName(), allQNames);
474 throw new IllegalArgumentException("Cannot find service interface " + serviceReference.getServiceInterfaceQName());
476 ModuleIdentifier removed = refNames.remove(serviceReference);
477 if (removed == null){
478 throw new InstanceNotFoundException("Cannot find " + serviceReference.getServiceInterfaceQName());
480 Entry<ServiceReferenceMXBeanImpl, ServiceReferenceJMXRegistration> entry = mBeans.remove(serviceReference);
482 throw new IllegalStateException("Possible code error: cannot remove from mBeans: " + serviceReference);
484 entry.getValue().close();
488 public synchronized void removeAllServiceReferences() {
490 for (ServiceReference serviceReference: mBeans.keySet()) {
492 removeServiceReference(serviceReference);
493 } catch (InstanceNotFoundException e) {
494 throw new IllegalStateException("Possible error in code", e);
500 public synchronized boolean removeServiceReferences(final ObjectName moduleObjectName) throws InstanceNotFoundException {
501 lookupRegistry.checkConfigBeanExists(moduleObjectName);
502 String factoryName = ObjectNameUtil.getFactoryName(moduleObjectName);
503 // check that service interface name exist
504 Set<String> serviceInterfaceQNames = factoryNamesToQNames.get(factoryName);
505 return removeServiceReferences(moduleObjectName, serviceInterfaceQNames);
509 private boolean removeServiceReferences(final ObjectName moduleObjectName, final Set<String> qNames) throws InstanceNotFoundException {
510 ObjectNameUtil.checkType(moduleObjectName, ObjectNameUtil.TYPE_MODULE);
512 Set<ServiceReference> serviceReferencesLinkingTo = findServiceReferencesLinkingTo(moduleObjectName, qNames);
513 for (ServiceReference sr : serviceReferencesLinkingTo) {
514 removeServiceReference(sr);
516 return serviceReferencesLinkingTo.isEmpty() == false;
519 private Set<ServiceReference> findServiceReferencesLinkingTo(final ObjectName moduleObjectName, final Set<String> serviceInterfaceQNames) {
520 String factoryName = ObjectNameUtil.getFactoryName(moduleObjectName);
521 if (serviceInterfaceQNames == null) {
522 LOGGER.warn("Possible error in code: cannot find factoryName {} in {}, object name {}", factoryName, factoryNamesToQNames, moduleObjectName);
523 throw new IllegalStateException("Possible error in code: cannot find annotations of existing factory " + factoryName);
525 String instanceName = ObjectNameUtil.getInstanceName(moduleObjectName);
526 ModuleIdentifier moduleIdentifier = new ModuleIdentifier(factoryName, instanceName);
527 Set<ServiceReference> result = new HashSet<>();
528 for (Entry<ServiceReference, ModuleIdentifier> entry : refNames.entrySet()) {
529 if (entry.getValue().equals(moduleIdentifier)) {
530 result.add(entry.getKey());
537 public String toString() {
538 return "ServiceReferenceRegistryImpl{" +
539 "lookupRegistry=" + lookupRegistry +
540 "refNames=" + refNames +
541 ", factoryNamesToQNames=" + factoryNamesToQNames +
546 public void close() {
547 serviceReferenceRegistrator.close();