import com.google.common.collect.Lists;
import java.util.List;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType;
import org.opendaylight.controller.netconf.util.xml.XmlElement;
public class ArrayAttributeReadingStrategy extends AbstractAttributeReadingStrategy {
@Override
AttributeConfigElement readElementHook(List<XmlElement> configNodes) throws NetconfDocumentedException {
List<Object> innerList = Lists.newArrayList();
+ EditStrategyType innerEditStrategy= null;
for (XmlElement configNode : configNodes) {
- innerList.add(innerStrategy.readElement(Lists.newArrayList(configNode)).getValue());
+ final AttributeConfigElement attributeConfigElement = innerStrategy.readElement(Lists.newArrayList(configNode));
+ if(attributeConfigElement.getEditStrategy().isPresent()) {
+ // TODO this sets the last operation for the entire array
+ innerEditStrategy = attributeConfigElement.getEditStrategy().get();
+ }
+ innerList.add(attributeConfigElement.getValue());
}
- return AttributeConfigElement.create(getNullableDefault(), innerList);
+ return innerEditStrategy == null ? AttributeConfigElement.create(getNullableDefault(), innerList) :
+ AttributeConfigElement.create(getNullableDefault(), innerList, innerEditStrategy);
}
}
import javax.management.openmbean.OpenType;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.resolving.AttributeResolvingStrategy;
+import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType;
/**
* Parsed xml element containing configuration for one attribute of an instance
public class AttributeConfigElement {
private final Object defaultValue;
private final Object value;
+ private final Optional<EditStrategyType> editStrategy;
private Optional<?> resolvedValue;
private Object resolvedDefaultValue;
private String jmxName;
- public AttributeConfigElement(Object defaultValue, Object value) {
+ public AttributeConfigElement(Object defaultValue, Object value, final EditStrategyType editStrategyType) {
this.defaultValue = defaultValue;
this.value = value;
+ this.editStrategy = Optional.fromNullable(editStrategyType);
}
public void setJmxName(String jmxName) {
resolvedDefaultValue = resolvedDefault.isPresent() ? resolvedDefault.get() : null;
}
+ public Optional<EditStrategyType> getEditStrategy() {
+ return editStrategy;
+ }
+
public static AttributeConfigElement create(Object nullableDefault, Object value) {
- return new AttributeConfigElement(nullableDefault, value);
+ return new AttributeConfigElement(nullableDefault, value, null);
}
public static AttributeConfigElement createNullValue(Object nullableDefault) {
- return new AttributeConfigElement(nullableDefault, null);
+ return new AttributeConfigElement(nullableDefault, null, null);
+ }
+
+ public static AttributeConfigElement create(final String nullableDefault, final Object value, final EditStrategyType editStrategyType) {
+ return new AttributeConfigElement(nullableDefault, value, editStrategyType);
}
public Object getValue() {
package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml;
import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
+import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType;
import org.opendaylight.controller.netconf.util.xml.XmlElement;
public class CompositeAttributeReadingStrategy extends AbstractAttributeReadingStrategy {
complexElement.checkUnrecognisedElements(recognisedChildren);
- return AttributeConfigElement.create(getNullableDefault(), innerMap);
+ String perInstanceEditStrategy = complexElement.getAttribute(XmlNetconfConstants.OPERATION_ATTR_KEY,
+ XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
+
+ return Strings.isNullOrEmpty(perInstanceEditStrategy) ? AttributeConfigElement.create(getNullableDefault(), innerMap) :
+ AttributeConfigElement.create(getNullableDefault(), innerMap, EditStrategyType.valueOf(perInstanceEditStrategy));
}
}
package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig;
+import java.util.Collections;
import java.util.Map;
import org.opendaylight.controller.config.util.ConfigTransactionClient;
+import org.opendaylight.controller.netconf.confignetconfconnector.exception.NetconfConfigHandlingException;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import org.slf4j.Logger;
@Override
public void executeConfiguration(String module, String instance, Map<String, AttributeConfigElement> configuration,
- ConfigTransactionClient ta, ServiceRegistryWrapper services) {
- LOG.debug("Skipping configuration element for {}:{}", module, instance);
+ ConfigTransactionClient ta, ServiceRegistryWrapper services) throws NetconfConfigHandlingException {
+ if(configuration != null && !configuration.isEmpty()) {
+ for (Map.Entry<String, AttributeConfigElement> attrEntry : configuration.entrySet()) {
+ if(attrEntry.getValue().getEditStrategy().isPresent()) {
+ final Map<String, AttributeConfigElement> partialConfig =
+ Collections.singletonMap(attrEntry.getKey(), attrEntry.getValue());
+ attrEntry.getValue().getEditStrategy().get().getFittingStrategy()
+ .executeConfiguration(module, instance, partialConfig, ta, services);
+ } else {
+ LOG.debug("Skipping configuration element for {}:{}:{}", module, instance, attrEntry.getKey());
+ }
+ }
+ } else {
+ LOG.debug("Skipping configuration element for {}:{}", module, instance);
+ }
}
}
package org.opendaylight.controller.netconf.confignetconfconnector;
import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import javax.management.InstanceAlreadyExistsException;
import javax.management.InstanceNotFoundException;
import javax.management.ObjectName;
import org.custommonkey.xmlunit.NodeTester;
import org.custommonkey.xmlunit.XMLAssert;
import org.custommonkey.xmlunit.XMLUnit;
-import org.hamcrest.CoreMatchers;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
edit("netconfMessages/editConfig_identities.xml");
commit();
- getConfigRunning();
+ Document configRunning = getConfigRunning();
+ String asString = XmlUtil.toString(configRunning);
+ assertThat(asString, containsString("test-identity2"));
+ assertThat(asString, containsString("test-identity1"));
+ assertEquals(2, countSubstringOccurence(asString, "</identities>"));
+
+ edit("netconfMessages/editConfig_identities_inner_replace.xml");
+ commit();
+ configRunning = getConfigRunning();
+ asString = XmlUtil.toString(configRunning);
+ // test-identity1 was removed by replace
+ assertThat(asString, not(containsString("test-identity2")));
+ // now only 1 identities entry is present
+ assertEquals(1, countSubstringOccurence(asString, "</identities>"));
+ }
+
+ private int countSubstringOccurence(final String string, final String substring) {
+ final Matcher matches = Pattern.compile(substring).matcher(string);
+ int count = 0;
+ while (matches.find()) {
+ count++;
+ }
+ return count;
}
@Override
}
private void assertContainsString(String string, String substring) {
- assertThat(string, CoreMatchers.containsString(substring));
+ assertThat(string, containsString(substring));
}
private void checkEnum(final Document response) throws Exception {
--- /dev/null
+<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+ <edit-config>
+ <target>
+ <candidate/>
+ </target>
+ <test-option>
+ set
+ </test-option>
+ <default-operation>none</default-operation>
+ <config>
+ <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+ <module xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
+ <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
+ test-impl:impl-identity-test
+ </type>
+ <name>id-test</name>
+ <identities xc:operation="replace">
+ <afi xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:test:types">prefix:test-identity1</afi>
+ <safi xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:test:types">prefix:test-identity1</safi>
+ </identities>
+ <identities-container xc:operation="replace">
+ <afi xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:test:types">prefix:test-identity1</afi>
+ </identities-container>
+ </module>
+ </modules>
+
+ <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+
+ </services>
+ </config>
+ </edit-config>
+</rpc>