2 * Copyright (c) 2013, 2017 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 com.google.common.base.Preconditions;
11 import com.google.common.collect.Lists;
12 import java.util.ArrayList;
13 import java.util.Collection;
14 import java.util.HashSet;
15 import java.util.List;
17 import java.util.Map.Entry;
19 import java.util.concurrent.atomic.AtomicBoolean;
20 import javax.annotation.Nullable;
21 import javax.annotation.concurrent.GuardedBy;
22 import javax.management.DynamicMBean;
23 import javax.management.InstanceAlreadyExistsException;
24 import javax.management.InstanceNotFoundException;
25 import javax.management.MBeanServer;
26 import javax.management.ObjectName;
27 import org.opendaylight.controller.config.api.DependencyResolver;
28 import org.opendaylight.controller.config.api.ModuleFactoryNotFoundException;
29 import org.opendaylight.controller.config.api.ModuleIdentifier;
30 import org.opendaylight.controller.config.api.ValidationException;
31 import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation;
32 import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
33 import org.opendaylight.controller.config.manager.impl.dependencyresolver.DependencyResolverManager;
34 import org.opendaylight.controller.config.manager.impl.dependencyresolver.ModuleInternalTransactionalInfo;
35 import org.opendaylight.controller.config.manager.impl.dynamicmbean.DynamicWritableWrapper;
36 import org.opendaylight.controller.config.manager.impl.dynamicmbean.ReadOnlyAtomicBoolean;
37 import org.opendaylight.controller.config.manager.impl.dynamicmbean.ReadOnlyAtomicBoolean.ReadOnlyAtomicBooleanImpl;
38 import org.opendaylight.controller.config.manager.impl.factoriesresolver.HierarchicalConfigMBeanFactoriesHolder;
39 import org.opendaylight.controller.config.manager.impl.jmx.TransactionModuleJMXRegistrator;
40 import org.opendaylight.controller.config.manager.impl.jmx.TransactionModuleJMXRegistrator.TransactionModuleJMXRegistration;
41 import org.opendaylight.controller.config.manager.impl.osgi.mapping.BindingContextProvider;
42 import org.opendaylight.controller.config.manager.impl.util.InterfacesHelper;
43 import org.opendaylight.controller.config.spi.AbstractModule;
44 import org.opendaylight.controller.config.spi.Module;
45 import org.opendaylight.controller.config.spi.ModuleFactory;
46 import org.opendaylight.yangtools.concepts.Identifiable;
47 import org.osgi.framework.BundleContext;
48 import org.slf4j.Logger;
49 import org.slf4j.LoggerFactory;
52 * This is a JMX bean representing current transaction. It contains transaction
53 * identifier, unique version and parent version for optimistic locking.
55 public class ConfigTransactionControllerImpl implements ConfigTransactionControllerInternal,
56 ConfigTransactionControllerImplMXBean, Identifiable<TransactionIdentifier> {
57 private static final Logger LOG = LoggerFactory.getLogger(ConfigTransactionControllerImpl.class);
59 private final ConfigTransactionLookupRegistry txLookupRegistry;
60 private final ObjectName controllerON;
62 private final long parentVersion;
63 private final long currentVersion;
64 private final HierarchicalConfigMBeanFactoriesHolder factoriesHolder;
65 private final DependencyResolverManager dependencyResolverManager;
66 private final TransactionStatus transactionStatus;
67 private final MBeanServer transactionsMBeanServer;
68 private final Map<String, Map.Entry<ModuleFactory, BundleContext>> currentlyRegisteredFactories;
71 * Disables ability of {@link DynamicWritableWrapper} to change attributes
75 private final AtomicBoolean configBeanModificationDisabled = new AtomicBoolean(false);
76 private final ReadOnlyAtomicBoolean readOnlyAtomicBoolean = new ReadOnlyAtomicBooleanImpl(
77 configBeanModificationDisabled);
78 private final MBeanServer configMBeanServer;
80 private final boolean blankTransaction;
83 private final SearchableServiceReferenceWritableRegistry writableSRRegistry;
85 public ConfigTransactionControllerImpl(final ConfigTransactionLookupRegistry txLookupRegistry,
86 final long parentVersion, final BindingContextProvider bindingContextProvider, final long currentVersion,
87 final Map<String, Entry<ModuleFactory, BundleContext>> currentlyRegisteredFactories,
88 final MBeanServer transactionsMBeanServer, final MBeanServer configMBeanServer,
89 final boolean blankTransaction, final SearchableServiceReferenceWritableRegistry writableSRRegistry) {
90 this.txLookupRegistry = txLookupRegistry;
91 String transactionName = txLookupRegistry.getTransactionIdentifier().getName();
92 this.controllerON = ObjectNameUtil.createTransactionControllerON(transactionName);
93 this.parentVersion = parentVersion;
94 this.currentVersion = currentVersion;
95 this.currentlyRegisteredFactories = currentlyRegisteredFactories;
96 this.factoriesHolder = new HierarchicalConfigMBeanFactoriesHolder(currentlyRegisteredFactories);
97 this.transactionStatus = new TransactionStatus();
98 this.dependencyResolverManager = new DependencyResolverManager(txLookupRegistry.getTransactionIdentifier(),
99 transactionStatus, writableSRRegistry, bindingContextProvider, transactionsMBeanServer);
100 this.transactionsMBeanServer = transactionsMBeanServer;
101 this.configMBeanServer = configMBeanServer;
102 this.blankTransaction = blankTransaction;
103 this.writableSRRegistry = writableSRRegistry;
107 public void copyExistingModulesAndProcessFactoryDiff(final Collection<ModuleInternalInfo> existingModules,
108 final List<ModuleFactory> lastListOfFactories) {
109 // copy old configuration to this server
110 for (ModuleInternalInfo oldConfigInfo : existingModules) {
112 copyExistingModule(oldConfigInfo);
113 } catch (final InstanceAlreadyExistsException e) {
114 throw new IllegalStateException("Error while copying " + oldConfigInfo, e);
117 processDefaultBeans(lastListOfFactories);
120 private synchronized void processDefaultBeans(final List<ModuleFactory> lastListOfFactories) {
121 transactionStatus.checkNotCommitStarted();
122 transactionStatus.checkNotAborted();
124 Set<ModuleFactory> oldSet = new HashSet<>(lastListOfFactories);
125 Set<ModuleFactory> newSet = new HashSet<>(factoriesHolder.getModuleFactories());
127 List<ModuleFactory> toBeAdded = new ArrayList<>();
128 List<ModuleFactory> toBeRemoved = new ArrayList<>();
129 for (ModuleFactory moduleFactory : factoriesHolder.getModuleFactories()) {
130 if (!oldSet.contains(moduleFactory)) {
131 toBeAdded.add(moduleFactory);
134 for (ModuleFactory moduleFactory : lastListOfFactories) {
135 if (!newSet.contains(moduleFactory)) {
136 toBeRemoved.add(moduleFactory);
139 // add default modules
140 for (ModuleFactory moduleFactory : toBeAdded) {
141 BundleContext bundleContext = getModuleFactoryBundleContext(moduleFactory.getImplementationName());
142 Set<? extends Module> defaultModules = moduleFactory.getDefaultModules(dependencyResolverManager,
144 for (Module module : defaultModules) {
145 // ensure default module to be registered to jmx even if its module factory does
146 // not use dependencyResolverFactory
147 DependencyResolver dependencyResolver = dependencyResolverManager.getOrCreate(module.getIdentifier());
148 final ObjectName objectName;
150 boolean defaultBean = true;
151 objectName = putConfigBeanToJMXAndInternalMaps(module.getIdentifier(), module, moduleFactory, null,
152 dependencyResolver, defaultBean, bundleContext);
153 } catch (final InstanceAlreadyExistsException e) {
154 throw new IllegalStateException(e);
156 // register default module as every possible service
157 final Set<ServiceInterfaceAnnotation> serviceInterfaceAnnotations = InterfacesHelper
158 .getServiceInterfaceAnnotations(moduleFactory);
159 for (String qname : InterfacesHelper.getQNames(serviceInterfaceAnnotations)) {
161 saveServiceReference(qname, module.getIdentifier().getInstanceName(), objectName);
162 } catch (final InstanceNotFoundException e) {
163 throw new IllegalStateException(
164 "Unable to register default module instance " + module + " as a service of " + qname,
171 // remove modules belonging to removed factories
172 for (ModuleFactory removedFactory : toBeRemoved) {
173 List<ModuleIdentifier> modulesOfRemovedFactory = dependencyResolverManager.findAllByFactory(removedFactory);
174 for (ModuleIdentifier name : modulesOfRemovedFactory) {
175 // remove service refs
176 final ModuleFactory moduleFactory = dependencyResolverManager.findModuleInternalTransactionalInfo(name)
178 final Set<ServiceInterfaceAnnotation> serviceInterfaceAnnotations = InterfacesHelper
179 .getServiceInterfaceAnnotations(moduleFactory);
180 for (String qname : InterfacesHelper.getQNames(serviceInterfaceAnnotations)) {
182 removeServiceReference(qname, name.getInstanceName());
183 } catch (final InstanceNotFoundException e) {
184 throw new IllegalStateException(
185 "Unable to UNregister default module instance " + name + " as a service of " + qname,
195 @SuppressWarnings("IllegalCatch")
196 private synchronized void copyExistingModule(final ModuleInternalInfo oldConfigBeanInfo)
197 throws InstanceAlreadyExistsException {
199 transactionStatus.checkNotCommitStarted();
200 transactionStatus.checkNotAborted();
201 ModuleIdentifier moduleIdentifier = oldConfigBeanInfo.getIdentifier();
202 dependencyResolverManager.assertNotExists(moduleIdentifier);
204 ModuleFactory moduleFactory;
207 moduleFactory = factoriesHolder.findByModuleName(moduleIdentifier.getFactoryName());
208 bc = getModuleFactoryBundleContext(moduleFactory.getImplementationName());
209 } catch (final ModuleFactoryNotFoundException e) {
210 throw new IllegalStateException(e);
214 DependencyResolver dependencyResolver = dependencyResolverManager.getOrCreate(moduleIdentifier);
217 module = moduleFactory.createModule(moduleIdentifier.getInstanceName(), dependencyResolver,
218 oldConfigBeanInfo.getReadableModule(), bc);
219 } catch (final Exception e) {
220 throw new IllegalStateException(String.format("Error while copying old configuration from %s to %s",
221 oldConfigBeanInfo, moduleFactory), e);
223 putConfigBeanToJMXAndInternalMaps(moduleIdentifier, module, moduleFactory, oldConfigBeanInfo,
224 dependencyResolver, oldConfigBeanInfo.isDefaultBean(), bc);
228 public synchronized ObjectName createModule(final String factoryName, final String instanceName)
229 throws InstanceAlreadyExistsException {
231 transactionStatus.checkNotCommitStarted();
232 transactionStatus.checkNotAborted();
233 ModuleIdentifier moduleIdentifier = new ModuleIdentifier(factoryName, instanceName);
234 dependencyResolverManager.assertNotExists(moduleIdentifier);
237 ModuleFactory moduleFactory = factoriesHolder.findByModuleName(factoryName);
239 DependencyResolver dependencyResolver = dependencyResolverManager.getOrCreate(moduleIdentifier);
240 BundleContext bundleContext = getModuleFactoryBundleContext(moduleFactory.getImplementationName());
241 Module module = moduleFactory.createModule(instanceName, dependencyResolver, bundleContext);
242 boolean defaultBean = false;
243 return putConfigBeanToJMXAndInternalMaps(moduleIdentifier, module, moduleFactory, null, dependencyResolver,
244 defaultBean, bundleContext);
248 public synchronized void reCreateModule(final ObjectName objectName) throws InstanceNotFoundException {
249 transactionStatus.checkNotCommitStarted();
250 transactionStatus.checkNotAborted();
251 checkTransactionName(objectName);
252 ObjectNameUtil.checkDomain(objectName);
253 ModuleIdentifier moduleIdentifier = ObjectNameUtil.fromON(objectName, ObjectNameUtil.TYPE_MODULE);
255 ModuleInternalTransactionalInfo txInfo = dependencyResolverManager
256 .findModuleInternalTransactionalInfo(moduleIdentifier);
257 Module realModule = txInfo.getRealModule();
258 if (realModule instanceof AbstractModule) {
259 ((AbstractModule<?>) realModule).setCanReuseInstance(false);
263 private synchronized ObjectName putConfigBeanToJMXAndInternalMaps(final ModuleIdentifier moduleIdentifier,
264 final Module module, final ModuleFactory moduleFactory,
265 @Nullable final ModuleInternalInfo maybeOldConfigBeanInfo, final DependencyResolver dependencyResolver,
266 final boolean isDefaultBean, final BundleContext bundleContext) throws InstanceAlreadyExistsException {
268 LOG.debug("Adding module {} to transaction {}", moduleIdentifier, this);
269 if (!moduleIdentifier.equals(module.getIdentifier())) {
270 throw new IllegalStateException("Incorrect name reported by module. Expected " + moduleIdentifier + ", got "
271 + module.getIdentifier());
273 if (!dependencyResolver.getIdentifier().equals(moduleIdentifier)) {
274 throw new IllegalStateException("Incorrect name reported by dependency resolver. Expected "
275 + moduleIdentifier + ", got " + dependencyResolver.getIdentifier());
277 DynamicMBean writableDynamicWrapper = new DynamicWritableWrapper(module, moduleIdentifier,
278 getTransactionIdentifier().getName(), readOnlyAtomicBoolean, transactionsMBeanServer,
281 ObjectName writableON = ObjectNameUtil.createTransactionModuleON(getTransactionIdentifier().getName(),
283 // put wrapper to jmx
284 TransactionModuleJMXRegistration transactionModuleJMXRegistration = getTxModuleJMXRegistrator()
285 .registerMBean(writableDynamicWrapper, writableON);
287 dependencyResolverManager.put(moduleIdentifier, module, moduleFactory, maybeOldConfigBeanInfo,
288 transactionModuleJMXRegistration, isDefaultBean, bundleContext);
293 public synchronized void destroyModule(final ObjectName objectName) throws InstanceNotFoundException {
294 checkTransactionName(objectName);
295 ObjectNameUtil.checkDomain(objectName);
296 ModuleIdentifier moduleIdentifier = ObjectNameUtil.fromON(objectName, ObjectNameUtil.TYPE_MODULE);
297 destroyModule(moduleIdentifier);
300 private synchronized void destroyModule(final ModuleIdentifier moduleIdentifier) {
301 LOG.debug("Destroying module {} in transaction {}", moduleIdentifier, this);
302 transactionStatus.checkNotAborted();
304 ModuleInternalTransactionalInfo found = dependencyResolverManager
305 .findModuleInternalTransactionalInfo(moduleIdentifier);
306 if (!blankTransaction && found.isDefaultBean()) {
307 LOG.warn("Warning: removing default bean. This will be forbidden in next version of config-subsystem");
309 // first remove refNames, it checks for objectname existence
312 writableSRRegistry.removeServiceReferences(
313 ObjectNameUtil.createTransactionModuleON(getTransactionName(), moduleIdentifier));
314 } catch (final InstanceNotFoundException e) {
315 LOG.error("Possible code error: cannot find {} in {}", moduleIdentifier, writableSRRegistry);
316 throw new IllegalStateException("Possible code error: cannot find " + moduleIdentifier, e);
319 ModuleInternalTransactionalInfo removedTInfo = dependencyResolverManager.destroyModule(moduleIdentifier);
321 removedTInfo.getTransactionModuleJMXRegistration().close();
324 private void checkTransactionName(final ObjectName objectName) {
325 String foundTransactionName = ObjectNameUtil.getTransactionName(objectName);
326 if (!getTransactionIdentifier().getName().equals(foundTransactionName)) {
327 throw new IllegalArgumentException("Wrong transaction name " + objectName);
332 public long getParentVersion() {
333 return parentVersion;
337 public long getVersion() {
338 return currentVersion;
342 public synchronized void validateConfig() throws ValidationException {
343 if (configBeanModificationDisabled.get()) {
344 throw new IllegalStateException("Cannot start validation");
346 configBeanModificationDisabled.set(true);
350 configBeanModificationDisabled.set(false);
354 @SuppressWarnings("IllegalCatch")
355 private void validateNoLocks() throws ValidationException {
356 transactionStatus.checkNotAborted();
357 LOG.trace("Validating transaction {}", getTransactionIdentifier());
359 List<ValidationException> collectedExceptions = new ArrayList<>();
360 for (Entry<ModuleIdentifier, Module> entry : dependencyResolverManager.getAllModules().entrySet()) {
361 ModuleIdentifier name = entry.getKey();
362 Module module = entry.getValue();
365 } catch (final Exception e) {
366 LOG.warn("Validation exception in {}", getTransactionName(), e);
367 collectedExceptions.add(ValidationException.createForSingleException(name, e));
370 if (!collectedExceptions.isEmpty()) {
371 throw ValidationException.createFromCollectedValidationExceptions(collectedExceptions);
373 LOG.trace("Validated transaction {}", getTransactionIdentifier());
377 * If this method passes validation, it will grab
378 * {@link TransactionStatus#secondPhaseCommitStarted} lock. This lock will
379 * prevent calling @{link #validateBeforeCommitAndLockTransaction}, effectively
380 * only allowing to call {@link #secondPhaseCommit} after successful return of
384 public synchronized CommitInfo validateBeforeCommitAndLockTransaction() throws ValidationException {
385 transactionStatus.checkNotAborted();
386 transactionStatus.checkNotCommitStarted();
387 configBeanModificationDisabled.set(true);
390 } catch (final ValidationException e) {
391 LOG.trace("Commit failed on validation");
393 configBeanModificationDisabled.set(false);
396 // errors in this state are not recoverable. modules are not mutable
398 transactionStatus.setSecondPhaseCommitStarted();
399 return dependencyResolverManager.toCommitInfo();
406 public synchronized List<ModuleIdentifier> secondPhaseCommit() {
407 transactionStatus.checkNotAborted();
408 transactionStatus.checkCommitStarted();
409 if (!configBeanModificationDisabled.get()) {
410 throw new IllegalStateException(
411 "Internal error - validateBeforeCommitAndLockTransaction should be called " + "to obtain a lock");
414 LOG.trace("Committing transaction {}", getTransactionIdentifier());
416 Map<ModuleIdentifier, Module> allModules = dependencyResolverManager.getAllModules();
418 // call getInstance() on all Modules from top to bottom (from source to target
419 // of the dependency relation)
420 // The source of a dependency closes itself and calls getInstance recursively on
421 // the dependencies (in case of reconfiguration)
422 // This makes close() calls from top to bottom while createInstance() calls are
423 // performed bottom to top
424 List<ModuleIdentifier> sortedModuleIdentifiers = Lists
425 .reverse(dependencyResolverManager.getSortedModuleIdentifiers());
426 for (ModuleIdentifier moduleIdentifier : sortedModuleIdentifiers) {
427 Module module = allModules.get(moduleIdentifier);
429 LOG.debug("About to commit {} in transaction {}", moduleIdentifier, getTransactionIdentifier());
430 AutoCloseable instance = module.getInstance();
431 Preconditions.checkNotNull(instance, "Instance is null:%s in transaction %s", moduleIdentifier,
432 getTransactionIdentifier());
435 LOG.trace("Committed configuration {}", getTransactionIdentifier());
436 transactionStatus.setCommitted();
438 return sortedModuleIdentifiers;
442 public void abortConfig() {
443 transactionStatus.checkNotCommitStarted();
444 transactionStatus.checkNotAborted();
448 private void internalAbort() {
449 LOG.trace("Aborting {}", this);
450 transactionStatus.setAborted();
455 public void close() {
456 dependencyResolverManager.close();
457 txLookupRegistry.close();
461 public ObjectName getControllerObjectName() {
466 public String getTransactionName() {
467 return getTransactionIdentifier().getName();
474 public Set<ObjectName> lookupConfigBeans() {
475 return txLookupRegistry.lookupConfigBeans();
482 public Set<ObjectName> lookupConfigBeans(final String moduleName) {
483 return txLookupRegistry.lookupConfigBeans(moduleName);
490 public Set<ObjectName> lookupConfigBeans(final String moduleName, final String instanceName) {
491 return txLookupRegistry.lookupConfigBeans(moduleName, instanceName);
498 public ObjectName lookupConfigBean(final String moduleName, final String instanceName)
499 throws InstanceNotFoundException {
500 return txLookupRegistry.lookupConfigBean(moduleName, instanceName);
507 public void checkConfigBeanExists(final ObjectName objectName) throws InstanceNotFoundException {
508 txLookupRegistry.checkConfigBeanExists(objectName);
515 public Set<ObjectName> lookupRuntimeBeans() {
516 return txLookupRegistry.lookupRuntimeBeans();
523 public Set<ObjectName> lookupRuntimeBeans(final String moduleName, final String instanceName) {
524 return txLookupRegistry.lookupRuntimeBeans(moduleName, instanceName);
533 public Set<String> getAvailableModuleNames() {
534 return factoriesHolder.getModuleNames();
538 public boolean isClosed() {
539 return transactionStatus.isAbortedOrCommitted();
543 public String toString() {
544 return "transactionName=" + getTransactionName();
547 // @VisibleForTesting
549 TransactionModuleJMXRegistrator getTxModuleJMXRegistrator() {
550 return txLookupRegistry.getTxModuleJMXRegistrator();
553 public TransactionIdentifier getName() {
554 return getTransactionIdentifier();
558 public List<ModuleFactory> getCurrentlyRegisteredFactories() {
559 return new ArrayList<>(factoriesHolder.getModuleFactories());
563 public TransactionIdentifier getIdentifier() {
564 return getTransactionIdentifier();
568 public BundleContext getModuleFactoryBundleContext(final String factoryName) {
569 Map.Entry<ModuleFactory, BundleContext> factoryBundleContextEntry = this.currentlyRegisteredFactories
571 if (factoryBundleContextEntry == null || factoryBundleContextEntry.getValue() == null) {
572 throw new NullPointerException("Bundle context of " + factoryName + " ModuleFactory not found.");
574 return factoryBundleContextEntry.getValue();
577 // service reference functionality:
580 public synchronized ObjectName lookupConfigBeanByServiceInterfaceName(final String serviceInterfaceQName,
581 final String refName) {
582 return writableSRRegistry.lookupConfigBeanByServiceInterfaceName(serviceInterfaceQName, refName);
586 public synchronized Map<String, Map<String, ObjectName>> getServiceMapping() {
587 return writableSRRegistry.getServiceMapping();
591 public synchronized Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(
592 final String serviceInterfaceQName) {
593 return writableSRRegistry.lookupServiceReferencesByServiceInterfaceName(serviceInterfaceQName);
597 public synchronized Set<String> lookupServiceInterfaceNames(final ObjectName objectName)
598 throws InstanceNotFoundException {
599 return writableSRRegistry.lookupServiceInterfaceNames(objectName);
603 public synchronized String getServiceInterfaceName(final String namespace, final String localName) {
604 return writableSRRegistry.getServiceInterfaceName(namespace, localName);
608 public synchronized ObjectName saveServiceReference(final String serviceInterfaceName, final String refName,
609 final ObjectName moduleON) throws InstanceNotFoundException {
610 return writableSRRegistry.saveServiceReference(serviceInterfaceName, refName, moduleON);
614 public synchronized void removeServiceReference(final String serviceInterfaceName, final String refName)
615 throws InstanceNotFoundException {
616 writableSRRegistry.removeServiceReference(serviceInterfaceName, refName);
620 public synchronized void removeAllServiceReferences() {
621 writableSRRegistry.removeAllServiceReferences();
625 public boolean removeServiceReferences(final ObjectName objectName) throws InstanceNotFoundException {
626 return writableSRRegistry.removeServiceReferences(objectName);
630 public SearchableServiceReferenceWritableRegistry getWritableRegistry() {
631 return writableSRRegistry;
635 public TransactionIdentifier getTransactionIdentifier() {
636 return txLookupRegistry.getTransactionIdentifier();
640 public Set<String> getAvailableModuleFactoryQNames() {
641 return txLookupRegistry.getAvailableModuleFactoryQNames();
645 public void checkServiceReferenceExists(final ObjectName objectName) throws InstanceNotFoundException {
646 writableSRRegistry.checkServiceReferenceExists(objectName);
650 public ObjectName getServiceReference(final String serviceInterfaceQName, final String refName)
651 throws InstanceNotFoundException {
652 return writableSRRegistry.getServiceReference(serviceInterfaceQName, refName);