Also fix bug in config-netconf-connector where edit strategy was in global scope.
Change-Id: Ia09a11078c87ffa4c6fa8de34f0b69b438b6c50e
Signed-off-by: Tomas Olvecky <tolvecky@cisco.com>
the actual service-type which is actually required.";
mandatory true;
- type leafref {
- path "/config:services/config:service/config:type";
- }
+ type service-type-ref;
}
leaf name {
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
+import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType;
import org.opendaylight.controller.netconf.util.xml.XmlElement;
import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
import org.opendaylight.controller.netconf.util.xml.XmlUtil;
// TODO refactor, replace string representing namespace with namespace class
// TODO refactor, replace Map->Multimap with e.g. ConfigElementResolved
// class
- public Map<String, Multimap<String, ModuleElementResolved>> fromXml(XmlElement xml, Set<ObjectName> instancesForFillingServiceRefMapping) {
+ public Map<String, Multimap<String, ModuleElementResolved>> fromXml(XmlElement xml, Set<ObjectName> instancesForFillingServiceRefMapping,
+ EditStrategyType defaultEditStrategyType) {
Map<String, Multimap<String, ModuleElementResolved>> retVal = Maps.newHashMap();
List<XmlElement> recognisedChildren = Lists.newArrayList();
xml.checkUnrecognisedElements(recognisedChildren);
for (XmlElement moduleElement : moduleElements) {
- resolveModule(retVal, serviceTracker, moduleElement);
+ resolveModule(retVal, serviceTracker, moduleElement, defaultEditStrategyType);
}
return retVal;
}
private void resolveModule(Map<String, Multimap<String, ModuleElementResolved>> retVal, Services serviceTracker,
- XmlElement moduleElement) {
+ XmlElement moduleElement, EditStrategyType defaultStrategy) {
XmlElement typeElement = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.TYPE_KEY);
Entry<String, String> prefixToNamespace = typeElement.findNamespaceOfTextContent();
String moduleNamespace = prefixToNamespace.getValue();
}
ModuleElementResolved moduleElementResolved = moduleMapping.fromXml(moduleElement, serviceTracker,
- instanceName, moduleNamespace);
+ instanceName, moduleNamespace, defaultStrategy);
innerMap.put(factoryName, moduleElementResolved);
}
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.resolving.ObjectResolver;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.toxml.AttributeWritingStrategy;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.toxml.ObjectXmlWriter;
+import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType;
import org.opendaylight.controller.netconf.util.xml.XmlElement;
import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
import org.slf4j.Logger;
}
}
- public InstanceConfigElementResolved fromXml(XmlElement moduleElement, Services services, String moduleNamespace) {
+ public InstanceConfigElementResolved fromXml(XmlElement moduleElement, Services services, String moduleNamespace,
+ EditStrategyType defaultStrategy) {
Map<String, AttributeConfigElement> retVal = Maps.newHashMap();
Map<String, AttributeReadingStrategy> strats = new ObjectXmlReader().prepareReading(yangToAttrConfig);
XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
InstanceConfigElementResolved instanceConfigElementResolved = perInstanceEditStrategy.equals("") ? new InstanceConfigElementResolved(
- retVal) : new InstanceConfigElementResolved(perInstanceEditStrategy, retVal);
+ retVal, defaultStrategy) : new InstanceConfigElementResolved(perInstanceEditStrategy, retVal, defaultStrategy);
resolveConfiguration(instanceConfigElementResolved, services);
return instanceConfigElementResolved;
private final EditStrategyType editStrategy;
private final Map<String, AttributeConfigElement> configuration;
- public InstanceConfigElementResolved(String strat, Map<String, AttributeConfigElement> configuration) {
- EditStrategyType valueOf = checkStrategy(strat);
+ public InstanceConfigElementResolved(String currentStrategy, Map<String, AttributeConfigElement> configuration, EditStrategyType defaultStrategy) {
+ EditStrategyType valueOf = checkStrategy(currentStrategy, defaultStrategy);
this.editStrategy = valueOf;
this.configuration = configuration;
}
- EditStrategyType checkStrategy(String strat) {
- EditStrategyType valueOf = EditStrategyType.valueOf(strat);
- if (EditStrategyType.defaultStrategy().isEnforcing()) {
+ public InstanceConfigElementResolved(Map<String, AttributeConfigElement> configuration, EditStrategyType defaultStrategy) {
+ editStrategy = defaultStrategy;
+ this.configuration = configuration;
+ }
+
+
+ EditStrategyType checkStrategy(String currentStrategy, EditStrategyType defaultStrategy) {
+ EditStrategyType valueOf = EditStrategyType.valueOf(currentStrategy);
+ if (defaultStrategy.isEnforcing()) {
Preconditions
.checkArgument(
- valueOf == EditStrategyType.defaultStrategy(),
+ valueOf == defaultStrategy,
"With "
- + EditStrategyType.defaultStrategy()
+ + defaultStrategy
+ " as "
+ EditConfigXmlParser.DEFAULT_OPERATION_KEY
+ " operations on module elements are not permitted since the default option is restrictive");
return valueOf;
}
- public InstanceConfigElementResolved(Map<String, AttributeConfigElement> configuration) {
- editStrategy = EditStrategyType.defaultStrategy();
- this.configuration = configuration;
- }
public EditConfigStrategy getEditStrategy() {
return editStrategy.getFittingStrategy();
package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config;
import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
+import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType;
import org.opendaylight.controller.netconf.util.xml.XmlElement;
import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
import org.opendaylight.controller.netconf.util.xml.XmlUtil;
}
public ModuleElementResolved fromXml(XmlElement moduleElement, Services depTracker, String instanceName,
- String moduleNamespace) {
+ String moduleNamespace, EditStrategyType defaultStrategy) {
- InstanceConfigElementResolved ice = instanceConfig.fromXml(moduleElement, depTracker, moduleNamespace);
+ InstanceConfigElementResolved ice = instanceConfig.fromXml(moduleElement, depTracker, moduleNamespace, defaultStrategy);
return new ModuleElementResolved(instanceName, ice);
}
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementResolved;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation;
+import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfigXmlParser.EditConfigExecution;
import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
import org.opendaylight.controller.netconf.util.xml.XmlElement;
import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
}
private void executeTests(ConfigRegistryClient configRegistryClient,
- EditConfigXmlParser.EditConfigExecution editConfigExecution) throws NetconfDocumentedException {
+ EditConfigExecution editConfigExecution) throws NetconfDocumentedException {
try {
- test(configRegistryClient, editConfigExecution.resolvedXmlElements);
+ test(configRegistryClient, editConfigExecution.getResolvedXmlElements(), editConfigExecution.getDefaultStrategy());
} catch (IllegalStateException | JmxAttributeValidationException | ValidationException e) {
logger.warn("Test phase for {} failed", EditConfigXmlParser.EDIT_CONFIG, e);
final Map<String, String> errorInfo = new HashMap<>();
}
private void test(ConfigRegistryClient configRegistryClient,
- Map<String, Multimap<String, ModuleElementResolved>> resolvedModules) {
+ Map<String, Multimap<String, ModuleElementResolved>> resolvedModules, EditStrategyType editStrategyType) {
ObjectName taON = transactionProvider.getTestTransaction();
try {
// default strategy = replace wipes config
- if (EditStrategyType.defaultStrategy() == EditStrategyType.replace) {
+ if (editStrategyType == EditStrategyType.replace) {
transactionProvider.wipeTestTransaction(taON);
}
setOnTransaction(configRegistryClient, resolvedModules, taON);
ObjectName taON = transactionProvider.getOrCreateTransaction();
// default strategy = replace wipes config
- if (EditStrategyType.defaultStrategy() == EditStrategyType.replace) {
+ if (editConfigExecution.getDefaultStrategy() == EditStrategyType.replace) {
transactionProvider.wipeTransaction();
}
- setOnTransaction(configRegistryClient, editConfigExecution.resolvedXmlElements, taON);
+ setOnTransaction(configRegistryClient, editConfigExecution.getResolvedXmlElements(), taON);
}
private void setOnTransaction(ConfigRegistryClient configRegistryClient,
TransactionProvider transactionProvider, ConfigRegistryClient configRegistryClient)
throws NetconfDocumentedException {
- EditStrategyType.resetDefaultStrategy();
+ EditStrategyType editStrategyType = EditStrategyType.getDefaultStrategy();
xml.checkName(EditConfigXmlParser.EDIT_CONFIG);
xml.checkNamespace(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
if (defaultContent.isPresent()) {
String mergeStrategyString = defaultContent.get().getTextContent();
logger.trace("Setting merge strategy to {}", mergeStrategyString);
- EditStrategyType editStrategyType = EditStrategyType.valueOf(mergeStrategyString);
- // FIXME: thread safety, remove global state
- EditStrategyType.setDefaultStrategy(editStrategyType);
+ editStrategyType = EditStrategyType.valueOf(mergeStrategyString);
}
- // FIXME: thread safety, remove global state
Set<ObjectName> instancesForFillingServiceRefMapping = Collections.emptySet();
- if (EditStrategyType.defaultStrategy() == EditStrategyType.merge) {
+ if (editStrategyType == EditStrategyType.merge) {
instancesForFillingServiceRefMapping = Datastore.getInstanceQueryStrategy(targetDatastore, transactionProvider)
.queryInstances(configRegistryClient);
logger.trace("Pre-filling services from following instances: {}", instancesForFillingServiceRefMapping);
XmlElement configElement = xml.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.CONFIG_KEY);
- return new EditConfigXmlParser.EditConfigExecution(xml, cfgMapping, configElement, testOption, instancesForFillingServiceRefMapping);
+ return new EditConfigXmlParser.EditConfigExecution(xml, cfgMapping, configElement, testOption,
+ instancesForFillingServiceRefMapping, editStrategyType);
}
private void removeMountpointsFromConfig(XmlElement configElement, XmlElement mountpointsElement) {
@VisibleForTesting
static class EditConfigExecution {
- XmlElement editConfigXml;
- Map<String, Multimap<String, ModuleElementResolved>> resolvedXmlElements;
- TestOption testOption;
+ private final XmlElement editConfigXml;
+ private final Map<String, Multimap<String, ModuleElementResolved>> resolvedXmlElements;
+ private final TestOption testOption;
+ private final EditStrategyType defaultEditStrategyType;
- EditConfigExecution(XmlElement xml, Config configResolver, XmlElement configElement, TestOption testOption, Set<ObjectName> instancesForFillingServiceRefMapping) {
+ EditConfigExecution(XmlElement xml, Config configResolver, XmlElement configElement, TestOption testOption, Set<ObjectName> instancesForFillingServiceRefMapping,
+ EditStrategyType defaultStrategy) {
this.editConfigXml = xml;
- this.resolvedXmlElements = configResolver.fromXml(configElement, instancesForFillingServiceRefMapping);
+ this.resolvedXmlElements = configResolver.fromXml(configElement, instancesForFillingServiceRefMapping, defaultStrategy);
this.testOption = testOption;
+ this.defaultEditStrategyType = defaultStrategy;
}
boolean shouldTest() {
boolean shouldSet() {
return testOption == TestOption.set || testOption == TestOption.testThenSet;
}
+
+ Map<String, Multimap<String, ModuleElementResolved>> getResolvedXmlElements() {
+ return resolvedXmlElements;
+ }
+
+ EditStrategyType getDefaultStrategy() {
+ return defaultEditStrategyType;
+ }
}
}
import java.util.EnumSet;
import java.util.Set;
-import com.google.common.base.Preconditions;
-
//FIXME: make thread safe
public enum EditStrategyType {
// can be default
private static final Set<EditStrategyType> defaultStrats = EnumSet.of(merge, replace, none);
- private static EditStrategyType defaultStrat = merge;
-
- public static EditStrategyType defaultStrategy() {
- return defaultStrat;
- }
-
- public static void setDefaultStrategy(EditStrategyType strat) {
- Preconditions.checkArgument(strat.canBeDefault(), "Default edit strategy can be only of value " + defaultStrats
- + ", but was " + strat);
- defaultStrat = strat;
- }
-
- public static void resetDefaultStrategy() {
- setDefaultStrategy(EditStrategyType.merge);
+ public static EditStrategyType getDefaultStrategy() {
+ return merge;
}
public boolean isEnforcing() {
}
}
- private static final EnumSet<EditStrategyType> defaults;
-
- static {
- defaults = EnumSet.of(merge, replace, none);
- }
-
- private boolean canBeDefault() {
- return defaults.contains(this);
- }
-
public EditConfigStrategy getFittingStrategy() {
switch (this) {
case merge:
Config cfg = mock(Config.class);
XmlElement xmlElement = mock(XmlElement.class);
Set<ObjectName> instancesForFillingServiceRefMapping = Collections.emptySet();
- doReturn(resolvedXmlElements).when(cfg).fromXml(xmlElement, instancesForFillingServiceRefMapping);
+ EditStrategyType defaultStrategy = EditStrategyType.getDefaultStrategy();
+ doReturn(resolvedXmlElements).when(cfg).fromXml(xmlElement, instancesForFillingServiceRefMapping, defaultStrategy);
EditConfigExecution editConfigExecution = new EditConfigExecution(null, cfg, xmlElement,
- EditConfigXmlParser.TestOption.testThenSet, instancesForFillingServiceRefMapping);
+ EditConfigXmlParser.TestOption.testThenSet, instancesForFillingServiceRefMapping, defaultStrategy);
edit.getResponseInternal(XmlUtil.newDocument(), editConfigExecution);