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 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
53 * transaction identifier, unique version and parent version for
56 class ConfigTransactionControllerImpl implements
57 ConfigTransactionControllerInternal,
58 ConfigTransactionControllerImplMXBean,
59 Identifiable<TransactionIdentifier> {
60 private static final Logger LOG = LoggerFactory.getLogger(ConfigTransactionControllerImpl.class);
62 private final ConfigTransactionLookupRegistry txLookupRegistry;
63 private final ObjectName controllerON;
65 private final long parentVersion;
66 private final long currentVersion;
67 private final HierarchicalConfigMBeanFactoriesHolder factoriesHolder;
68 private final DependencyResolverManager dependencyResolverManager;
69 private final TransactionStatus transactionStatus;
70 private final MBeanServer transactionsMBeanServer;
71 private final Map<String, Map.Entry<ModuleFactory, BundleContext>> currentlyRegisteredFactories;
74 * Disables ability of {@link DynamicWritableWrapper} to change attributes
78 private final AtomicBoolean configBeanModificationDisabled = new AtomicBoolean(
80 private final ReadOnlyAtomicBoolean readOnlyAtomicBoolean = new ReadOnlyAtomicBooleanImpl(
81 configBeanModificationDisabled);
82 private final MBeanServer configMBeanServer;
84 private final boolean blankTransaction;
87 private final SearchableServiceReferenceWritableRegistry writableSRRegistry;
89 public ConfigTransactionControllerImpl(final ConfigTransactionLookupRegistry txLookupRegistry,
90 final long parentVersion, final BindingContextProvider bindingContextProvider, final long currentVersion,
91 final Map<String, Entry<ModuleFactory, BundleContext>> currentlyRegisteredFactories,
92 final MBeanServer transactionsMBeanServer, final MBeanServer configMBeanServer,
93 final boolean blankTransaction, final SearchableServiceReferenceWritableRegistry writableSRRegistry) {
94 this.txLookupRegistry = txLookupRegistry;
95 String transactionName = txLookupRegistry.getTransactionIdentifier().getName();
96 this.controllerON = ObjectNameUtil.createTransactionControllerON(transactionName);
97 this.parentVersion = parentVersion;
98 this.currentVersion = currentVersion;
99 this.currentlyRegisteredFactories = currentlyRegisteredFactories;
100 this.factoriesHolder = new HierarchicalConfigMBeanFactoriesHolder(currentlyRegisteredFactories);
101 this.transactionStatus = new TransactionStatus();
102 this.dependencyResolverManager = new DependencyResolverManager(txLookupRegistry.getTransactionIdentifier(),
103 transactionStatus, writableSRRegistry, bindingContextProvider, transactionsMBeanServer);
104 this.transactionsMBeanServer = transactionsMBeanServer;
105 this.configMBeanServer = configMBeanServer;
106 this.blankTransaction = blankTransaction;
107 this.writableSRRegistry = writableSRRegistry;
111 public void copyExistingModulesAndProcessFactoryDiff(final Collection<ModuleInternalInfo> existingModules, final List<ModuleFactory> lastListOfFactories) {
112 // copy old configuration to this server
113 for (ModuleInternalInfo oldConfigInfo : existingModules) {
115 copyExistingModule(oldConfigInfo);
116 } catch (final InstanceAlreadyExistsException e) {
117 throw new IllegalStateException("Error while copying " + oldConfigInfo, e);
120 processDefaultBeans(lastListOfFactories);
123 private synchronized void processDefaultBeans(final List<ModuleFactory> lastListOfFactories) {
124 transactionStatus.checkNotCommitStarted();
125 transactionStatus.checkNotAborted();
127 Set<ModuleFactory> oldSet = new HashSet<>(lastListOfFactories);
128 Set<ModuleFactory> newSet = new HashSet<>(factoriesHolder.getModuleFactories());
130 List<ModuleFactory> toBeAdded = new ArrayList<>();
131 List<ModuleFactory> toBeRemoved = new ArrayList<>();
132 for (ModuleFactory moduleFactory : factoriesHolder.getModuleFactories()) {
133 if (!oldSet.contains(moduleFactory)) {
134 toBeAdded.add(moduleFactory);
137 for (ModuleFactory moduleFactory : lastListOfFactories) {
138 if (!newSet.contains(moduleFactory)) {
139 toBeRemoved.add(moduleFactory);
142 // add default modules
143 for (ModuleFactory moduleFactory : toBeAdded) {
144 BundleContext bundleContext = getModuleFactoryBundleContext(moduleFactory.getImplementationName());
145 Set<? extends Module> defaultModules = moduleFactory.getDefaultModules(dependencyResolverManager,
147 for (Module module : defaultModules) {
148 // ensure default module to be registered to jmx even if its module factory does not use dependencyResolverFactory
149 DependencyResolver dependencyResolver = dependencyResolverManager.getOrCreate(module.getIdentifier());
150 final ObjectName objectName;
152 boolean defaultBean = true;
153 objectName = putConfigBeanToJMXAndInternalMaps(module.getIdentifier(), module, moduleFactory, null,
154 dependencyResolver, defaultBean, bundleContext);
155 } catch (final InstanceAlreadyExistsException e) {
156 throw new IllegalStateException(e);
159 // register default module as every possible service
160 final Set<ServiceInterfaceAnnotation> serviceInterfaceAnnotations = InterfacesHelper.getServiceInterfaceAnnotations(moduleFactory);
161 for (String qname : InterfacesHelper.getQNames(serviceInterfaceAnnotations)) {
163 saveServiceReference(qname, module.getIdentifier().getInstanceName(), objectName);
164 } catch (final InstanceNotFoundException e) {
165 throw new IllegalStateException("Unable to register default module instance " + module + " as a service of " + qname, e);
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).getModuleFactory();
177 final Set<ServiceInterfaceAnnotation> serviceInterfaceAnnotations = InterfacesHelper.getServiceInterfaceAnnotations(moduleFactory);
178 for (String qname : InterfacesHelper.getQNames(serviceInterfaceAnnotations)) {
180 removeServiceReference(qname, name.getInstanceName());
181 } catch (final InstanceNotFoundException e) {
182 throw new IllegalStateException("Unable to UNregister default module instance " + name + " as a service of " + qname, e);
193 private synchronized void copyExistingModule(final ModuleInternalInfo oldConfigBeanInfo)
194 throws InstanceAlreadyExistsException {
196 transactionStatus.checkNotCommitStarted();
197 transactionStatus.checkNotAborted();
198 ModuleIdentifier moduleIdentifier = oldConfigBeanInfo.getIdentifier();
199 dependencyResolverManager.assertNotExists(moduleIdentifier);
201 ModuleFactory moduleFactory;
204 moduleFactory = factoriesHolder.findByModuleName(moduleIdentifier.getFactoryName());
205 bc = getModuleFactoryBundleContext(moduleFactory.getImplementationName());
206 } catch (final ModuleFactoryNotFoundException e) {
207 throw new IllegalStateException(e);
211 DependencyResolver dependencyResolver = dependencyResolverManager.getOrCreate(moduleIdentifier);
214 module = moduleFactory.createModule(
215 moduleIdentifier.getInstanceName(), dependencyResolver,
216 oldConfigBeanInfo.getReadableModule(), bc);
217 } catch (final Exception e) {
218 throw new IllegalStateException(String.format(
219 "Error while copying old configuration from %s to %s",
220 oldConfigBeanInfo, moduleFactory), e);
222 putConfigBeanToJMXAndInternalMaps(moduleIdentifier, module, moduleFactory, oldConfigBeanInfo, dependencyResolver,
223 oldConfigBeanInfo.isDefaultBean(), bc);
227 public synchronized ObjectName createModule(final String factoryName, final String instanceName)
228 throws InstanceAlreadyExistsException {
230 transactionStatus.checkNotCommitStarted();
231 transactionStatus.checkNotAborted();
232 ModuleIdentifier moduleIdentifier = new ModuleIdentifier(factoryName, instanceName);
233 dependencyResolverManager.assertNotExists(moduleIdentifier);
236 ModuleFactory moduleFactory = factoriesHolder.findByModuleName(factoryName);
238 DependencyResolver dependencyResolver = dependencyResolverManager.getOrCreate(moduleIdentifier);
239 BundleContext bundleContext = getModuleFactoryBundleContext(moduleFactory.getImplementationName());
240 Module module = moduleFactory.createModule(instanceName, dependencyResolver,
242 boolean defaultBean = false;
243 return putConfigBeanToJMXAndInternalMaps(moduleIdentifier, module,
244 moduleFactory, null, dependencyResolver, 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.findModuleInternalTransactionalInfo(moduleIdentifier);
256 Module realModule = txInfo.getRealModule();
257 if(realModule instanceof AbstractModule) {
258 ((AbstractModule<?>)realModule).setCanReuseInstance(false);
262 private synchronized ObjectName putConfigBeanToJMXAndInternalMaps(
263 final ModuleIdentifier moduleIdentifier, final Module module,
264 final ModuleFactory moduleFactory,
265 @Nullable final ModuleInternalInfo maybeOldConfigBeanInfo, final DependencyResolver dependencyResolver,
266 final boolean isDefaultBean, final BundleContext bundleContext)
267 throws InstanceAlreadyExistsException {
269 LOG.debug("Adding module {} to transaction {}", moduleIdentifier, this);
270 if (!moduleIdentifier.equals(module.getIdentifier())) {
271 throw new IllegalStateException("Incorrect name reported by module. Expected "
272 + moduleIdentifier + ", got " + module.getIdentifier());
274 if (!dependencyResolver.getIdentifier().equals(moduleIdentifier)) {
275 throw new IllegalStateException("Incorrect name reported by dependency resolver. Expected "
276 + moduleIdentifier + ", got " + dependencyResolver.getIdentifier());
278 DynamicMBean writableDynamicWrapper = new DynamicWritableWrapper(
279 module, moduleIdentifier, getTransactionIdentifier().getName(),
280 readOnlyAtomicBoolean, transactionsMBeanServer,
283 ObjectName writableON = ObjectNameUtil.createTransactionModuleON(
284 getTransactionIdentifier().getName(), moduleIdentifier);
285 // put wrapper to jmx
286 TransactionModuleJMXRegistration transactionModuleJMXRegistration = getTxModuleJMXRegistrator()
287 .registerMBean(writableDynamicWrapper, writableON);
289 dependencyResolverManager.put(
290 moduleIdentifier, module, moduleFactory,
291 maybeOldConfigBeanInfo, transactionModuleJMXRegistration, isDefaultBean, bundleContext);
296 public synchronized void destroyModule(final ObjectName objectName) throws InstanceNotFoundException {
297 checkTransactionName(objectName);
298 ObjectNameUtil.checkDomain(objectName);
299 ModuleIdentifier moduleIdentifier = ObjectNameUtil.fromON(objectName,
300 ObjectNameUtil.TYPE_MODULE);
301 destroyModule(moduleIdentifier);
304 private void checkTransactionName(final ObjectName objectName) {
305 String foundTransactionName = ObjectNameUtil
306 .getTransactionName(objectName);
307 if (!getTransactionIdentifier().getName().equals(foundTransactionName)) {
308 throw new IllegalArgumentException("Wrong transaction name "
313 private synchronized void destroyModule(final ModuleIdentifier moduleIdentifier) {
314 LOG.debug("Destroying module {} in transaction {}", moduleIdentifier, this);
315 transactionStatus.checkNotAborted();
317 ModuleInternalTransactionalInfo found = dependencyResolverManager.findModuleInternalTransactionalInfo(moduleIdentifier);
318 if (!blankTransaction &&
319 found.isDefaultBean()) {
320 LOG.warn("Warning: removing default bean. This will be forbidden in next version of config-subsystem");
322 // first remove refNames, it checks for objectname existence
325 writableSRRegistry.removeServiceReferences(
326 ObjectNameUtil.createTransactionModuleON(getTransactionName(), moduleIdentifier));
327 } catch (final InstanceNotFoundException e) {
328 LOG.error("Possible code error: cannot find {} in {}", moduleIdentifier, writableSRRegistry);
329 throw new IllegalStateException("Possible code error: cannot find " + moduleIdentifier, e);
332 ModuleInternalTransactionalInfo removedTInfo = dependencyResolverManager.destroyModule(moduleIdentifier);
334 removedTInfo.getTransactionModuleJMXRegistration().close();
338 public long getParentVersion() {
339 return parentVersion;
343 public long getVersion() {
344 return currentVersion;
348 public synchronized void validateConfig() throws ValidationException {
349 if (configBeanModificationDisabled.get()) {
350 throw new IllegalStateException("Cannot start validation");
352 configBeanModificationDisabled.set(true);
356 configBeanModificationDisabled.set(false);
360 private void validateNoLocks() throws ValidationException {
361 transactionStatus.checkNotAborted();
362 LOG.trace("Validating transaction {}", getTransactionIdentifier());
364 List<ValidationException> collectedExceptions = new ArrayList<>();
365 for (Entry<ModuleIdentifier, Module> entry : dependencyResolverManager
366 .getAllModules().entrySet()) {
367 ModuleIdentifier name = entry.getKey();
368 Module module = entry.getValue();
371 } catch (final Exception e) {
372 LOG.warn("Validation exception in {}", getTransactionName(),
374 collectedExceptions.add(ValidationException
375 .createForSingleException(name, e));
378 if (!collectedExceptions.isEmpty()) {
379 throw ValidationException
380 .createFromCollectedValidationExceptions(collectedExceptions);
382 LOG.trace("Validated transaction {}", getTransactionIdentifier());
386 * If this method passes validation, it will grab
387 * {@link TransactionStatus#secondPhaseCommitStarted} lock. This lock will
388 * prevent calling @{link #validateBeforeCommitAndLockTransaction},
389 * effectively only allowing to call {@link #secondPhaseCommit} after
390 * successful return of this method.
393 public synchronized CommitInfo validateBeforeCommitAndLockTransaction()
394 throws ValidationException {
395 transactionStatus.checkNotAborted();
396 transactionStatus.checkNotCommitStarted();
397 configBeanModificationDisabled.set(true);
400 } catch (final ValidationException e) {
401 LOG.trace("Commit failed on validation");
403 configBeanModificationDisabled.set(false);
406 // errors in this state are not recoverable. modules are not mutable
408 transactionStatus.setSecondPhaseCommitStarted();
409 return dependencyResolverManager.toCommitInfo();
416 public synchronized List<ModuleIdentifier> secondPhaseCommit() {
417 transactionStatus.checkNotAborted();
418 transactionStatus.checkCommitStarted();
419 if (!configBeanModificationDisabled.get()) {
420 throw new IllegalStateException(
421 "Internal error - validateBeforeCommitAndLockTransaction should be called "
422 + "to obtain a lock");
425 LOG.trace("Committing transaction {}", getTransactionIdentifier());
427 Map<ModuleIdentifier, Module> allModules = dependencyResolverManager.getAllModules();
429 // call getInstance() on all Modules from top to bottom (from source to target of the dependency relation)
430 // The source of a dependency closes itself and calls getInstance recursively on the dependencies (in case of reconfiguration)
431 // This makes close() calls from top to bottom while createInstance() calls are performed bottom to top
432 List<ModuleIdentifier> sortedModuleIdentifiers = Lists.reverse(dependencyResolverManager.getSortedModuleIdentifiers());
433 for (ModuleIdentifier moduleIdentifier : sortedModuleIdentifiers) {
434 Module module = allModules.get(moduleIdentifier);
437 LOG.debug("About to commit {} in transaction {}",
438 moduleIdentifier, getTransactionIdentifier());
439 AutoCloseable instance = module.getInstance();
440 Preconditions.checkNotNull(instance, "Instance is null:{} in transaction {}", moduleIdentifier, getTransactionIdentifier());
441 } catch (final Exception e) {
442 LOG.error("Commit failed on {} in transaction {}", moduleIdentifier,
443 getTransactionIdentifier(), e);
445 throw new IllegalStateException(
446 String.format("Error - getInstance() failed for %s in transaction %s",
447 moduleIdentifier, getTransactionIdentifier()), e);
451 LOG.trace("Committed configuration {}", getTransactionIdentifier());
452 transactionStatus.setCommitted();
454 return sortedModuleIdentifiers;
458 public void abortConfig() {
459 transactionStatus.checkNotCommitStarted();
460 transactionStatus.checkNotAborted();
464 private void internalAbort() {
465 LOG.trace("Aborting {}", this);
466 transactionStatus.setAborted();
471 public void close() {
472 dependencyResolverManager.close();
473 txLookupRegistry.close();
477 public ObjectName getControllerObjectName() {
482 public String getTransactionName() {
483 return getTransactionIdentifier().getName();
490 public Set<ObjectName> lookupConfigBeans() {
491 return txLookupRegistry.lookupConfigBeans();
498 public Set<ObjectName> lookupConfigBeans(final String moduleName) {
499 return txLookupRegistry.lookupConfigBeans(moduleName);
506 public ObjectName lookupConfigBean(final String moduleName, final String instanceName)
507 throws InstanceNotFoundException {
508 return txLookupRegistry.lookupConfigBean(moduleName, instanceName);
515 public Set<ObjectName> lookupConfigBeans(final String moduleName, final String instanceName) {
516 return txLookupRegistry.lookupConfigBeans(moduleName, instanceName);
523 public void checkConfigBeanExists(final ObjectName objectName) throws InstanceNotFoundException {
524 txLookupRegistry.checkConfigBeanExists(objectName);
532 public Set<ObjectName> lookupRuntimeBeans() {
533 return txLookupRegistry.lookupRuntimeBeans();
540 public Set<ObjectName> lookupRuntimeBeans(final String moduleName,
541 final String instanceName) {
542 return txLookupRegistry.lookupRuntimeBeans(moduleName, instanceName);
551 public Set<String> getAvailableModuleNames() {
552 return factoriesHolder.getModuleNames();
556 public boolean isClosed() {
557 return transactionStatus.isAbortedOrCommitted();
561 public String toString() {
562 StringBuilder sb = new StringBuilder();
563 sb.append("transactionName=");
564 sb.append(getTransactionName());
565 return sb.toString();
568 // @VisibleForTesting
570 TransactionModuleJMXRegistrator getTxModuleJMXRegistrator() {
571 return txLookupRegistry.getTxModuleJMXRegistrator();
574 public TransactionIdentifier getName() {
575 return getTransactionIdentifier();
579 public List<ModuleFactory> getCurrentlyRegisteredFactories() {
580 return new ArrayList<>(factoriesHolder.getModuleFactories());
584 public TransactionIdentifier getIdentifier() {
585 return getTransactionIdentifier();
589 public BundleContext getModuleFactoryBundleContext(final String factoryName) {
590 Map.Entry<ModuleFactory, BundleContext> factoryBundleContextEntry = this.currentlyRegisteredFactories.get(factoryName);
591 if (factoryBundleContextEntry == null || factoryBundleContextEntry.getValue() == null) {
592 throw new NullPointerException("Bundle context of " + factoryName + " ModuleFactory not found.");
594 return factoryBundleContextEntry.getValue();
597 // service reference functionality:
601 public synchronized ObjectName lookupConfigBeanByServiceInterfaceName(final String serviceInterfaceQName, final String refName) {
602 return writableSRRegistry.lookupConfigBeanByServiceInterfaceName(serviceInterfaceQName, refName);
606 public synchronized Map<String, Map<String, ObjectName>> getServiceMapping() {
607 return writableSRRegistry.getServiceMapping();
611 public synchronized Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(final String serviceInterfaceQName) {
612 return writableSRRegistry.lookupServiceReferencesByServiceInterfaceName(serviceInterfaceQName);
616 public synchronized Set<String> lookupServiceInterfaceNames(final ObjectName objectName) throws InstanceNotFoundException {
617 return writableSRRegistry.lookupServiceInterfaceNames(objectName);
621 public synchronized String getServiceInterfaceName(final String namespace, final String localName) {
622 return writableSRRegistry.getServiceInterfaceName(namespace, localName);
626 public synchronized ObjectName saveServiceReference(final String serviceInterfaceName, final String refName, final ObjectName moduleON) throws InstanceNotFoundException {
627 return writableSRRegistry.saveServiceReference(serviceInterfaceName, refName, moduleON);
631 public synchronized void removeServiceReference(final String serviceInterfaceName, final String refName) throws InstanceNotFoundException {
632 writableSRRegistry.removeServiceReference(serviceInterfaceName, refName);
636 public synchronized void removeAllServiceReferences() {
637 writableSRRegistry.removeAllServiceReferences();
641 public boolean removeServiceReferences(final ObjectName objectName) throws InstanceNotFoundException {
642 return writableSRRegistry.removeServiceReferences(objectName);
646 public SearchableServiceReferenceWritableRegistry getWritableRegistry() {
647 return writableSRRegistry;
651 public TransactionIdentifier getTransactionIdentifier() {
652 return txLookupRegistry.getTransactionIdentifier();
656 public Set<String> getAvailableModuleFactoryQNames() {
657 return txLookupRegistry.getAvailableModuleFactoryQNames();
661 public void checkServiceReferenceExists(final ObjectName objectName) throws InstanceNotFoundException {
662 writableSRRegistry.checkServiceReferenceExists(objectName);
666 public ObjectName getServiceReference(final String serviceInterfaceQName, final String refName) throws InstanceNotFoundException {
667 return writableSRRegistry.getServiceReference(serviceInterfaceQName, refName);