ObjectName createModule(String moduleName, String instanceName)
throws InstanceAlreadyExistsException;
+ /**
+ * Re-creates an existing module configuration bean.
+ *
+ * @param objectName
+ * can be either read-only module name that can be obtained using
+ * {@link ConfigRegistry#lookupConfigBean(String, String)} or
+ * writable module name that must contain current transaction name.
+ * @throws InstanceNotFoundException
+ * if module is not found
+ * @throws IllegalArgumentException
+ * if object name contains wrong transaction name or domain
+ */
+ void reCreateModule(ObjectName objectName) throws InstanceNotFoundException;
+
/**
* Destroy existing module.
*
private AutoCloseable oldInstance;
private M oldModule;
private AutoCloseable instance;
+ private boolean canReuseInstance = true;
/**
* Called when module is configured.
return identifier;
}
+ public final void setCanReuseInstance(boolean canReuseInstance) {
+ this.canReuseInstance = canReuseInstance;
+ }
+
/**
*
* General algorithm for spawning/closing and reusing wrapped instances.
@Override
public final AutoCloseable getInstance() {
if (instance == null) {
- if (oldInstance != null && canReuseInstance(oldModule)) {
+ if (oldInstance != null && canReuseInstance && canReuseInstance(oldModule)) {
resolveDependencies();
instance = reuseInstance(oldInstance);
} else {
public final boolean canReuse(final Module oldModule) {
// Just cast into a specific instance
// TODO unify this method with canReuseInstance (required Module interface to be generic which requires quite a lot of changes)
- return getClass().isInstance(oldModule) ? canReuseInstance((M) oldModule) : false;
+ return canReuseInstance && getClass().isInstance(oldModule) ? canReuseInstance((M) oldModule) : false;
}
/**
package org.opendaylight.controller.config.facade.xml.mapping.config;
import static com.google.common.base.Preconditions.checkState;
-
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.collect.HashMultimap;
return dataElement;
}
+ public Element moduleToXml(String moduleNamespace, String factoryName, String instanceName,
+ ObjectName instanceON, Document document) {
+ ModuleConfig moduleConfig = getModuleMapping(moduleNamespace, instanceName, factoryName);
+ return moduleConfig.toXml(instanceON, document, moduleNamespace, enumResolver);
+ }
+
// TODO refactor, replace string representing namespace with namespace class
// TODO refactor, replace Map->Multimap with e.g. ConfigElementResolved
// class
// can be default
merge, replace, none,
// additional per element
- delete, remove;
+ delete, remove, recreate;
private static final Set<EditStrategyType> defaultStrats = EnumSet.of(merge, replace, none);
case none:
case remove:
case delete:
+ case recreate:
return false;
case replace:
return true;
return new DeleteEditConfigStrategy();
case remove:
return new RemoveEditConfigStrategy();
+ case recreate:
+ return new ReCreateEditConfigStrategy();
case none:
return new NoneEditConfigStrategy();
default:
--- /dev/null
+/*
+ * Copyright (c) 2016 Brocade Communications Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.config.facade.xml.strategy;
+
+import java.util.Map;
+import javax.management.InstanceNotFoundException;
+import javax.management.ObjectName;
+import org.opendaylight.controller.config.facade.xml.exception.ConfigHandlingException;
+import org.opendaylight.controller.config.facade.xml.mapping.attributes.fromxml.AttributeConfigElement;
+import org.opendaylight.controller.config.facade.xml.mapping.config.ServiceRegistryWrapper;
+import org.opendaylight.controller.config.util.ConfigTransactionClient;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+
+/**
+ * Edit strategy that forces re-creation of a module instance even if the config didn't change.
+ *
+ * @author Thomas Pantelis
+ */
+public class ReCreateEditConfigStrategy extends AbstractEditConfigStrategy {
+
+ @Override
+ void handleMissingInstance(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
+ String module, String instance, ServiceRegistryWrapper services) throws ConfigHandlingException {
+ throw new ConfigHandlingException(
+ String.format("Unable to recreate %s : %s, Existing module instance not found", module, instance),
+ DocumentedException.ErrorType.application,
+ DocumentedException.ErrorTag.operation_failed,
+ DocumentedException.ErrorSeverity.error);
+ }
+
+ @Override
+ void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
+ ObjectName objectName, ServiceRegistryWrapper services) throws ConfigHandlingException {
+ try {
+ ta.reCreateModule(objectName);
+ } catch(InstanceNotFoundException e) {
+ throw new ConfigHandlingException(String.format("Unable to recreate instance for %s", objectName),
+ DocumentedException.ErrorType.application,
+ DocumentedException.ErrorTag.operation_failed,
+ DocumentedException.ErrorSeverity.error);
+ }
+ }
+}
import org.opendaylight.controller.config.manager.impl.jmx.TransactionModuleJMXRegistrator.TransactionModuleJMXRegistration;
import org.opendaylight.controller.config.manager.impl.osgi.mapping.BindingContextProvider;
import org.opendaylight.controller.config.manager.impl.util.InterfacesHelper;
+import org.opendaylight.controller.config.spi.AbstractModule;
import org.opendaylight.controller.config.spi.Module;
import org.opendaylight.controller.config.spi.ModuleFactory;
import org.opendaylight.yangtools.concepts.Identifiable;
moduleFactory, null, dependencyResolver, defaultBean, bundleContext);
}
+ @Override
+ public synchronized void reCreateModule(ObjectName objectName) throws InstanceNotFoundException {
+ transactionStatus.checkNotCommitStarted();
+ transactionStatus.checkNotAborted();
+ checkTransactionName(objectName);
+ ObjectNameUtil.checkDomain(objectName);
+ ModuleIdentifier moduleIdentifier = ObjectNameUtil.fromON(objectName, ObjectNameUtil.TYPE_MODULE);
+
+ ModuleInternalTransactionalInfo txInfo = dependencyResolverManager.findModuleInternalTransactionalInfo(moduleIdentifier);
+ Module realModule = txInfo.getRealModule();
+ if(realModule instanceof AbstractModule) {
+ ((AbstractModule<?>)realModule).setCanReuseInstance(false);
+ }
+ }
+
private synchronized ObjectName putConfigBeanToJMXAndInternalMaps(
ModuleIdentifier moduleIdentifier, Module module,
ModuleFactory moduleFactory,
return configTransactionControllerMXBeanProxy.createModule(moduleName, instanceName);
}
+ @Override
+ public void reCreateModule(ObjectName objectName) throws InstanceNotFoundException {
+ configTransactionControllerMXBeanProxy.reCreateModule(objectName);
+ }
+
@Override
public void destroyModule(ObjectName objectName)
throws InstanceNotFoundException {
+ "=" + moduleName);
}
+ @Override
+ public void reCreateModule(ObjectName objectName) {
+ }
+
@Override
public void destroyModule(ObjectName objectName)
throws InstanceNotFoundException {