We are emitting "type" with the NETCONF base namespace.
This is wrong, as attributes are not subject to default namespace, hence
we should be emitting it as a plain attribute -- it is interpreted in
the context of its defining element, which already is in NETCONF base
namespace.
JIRA: NETCONF-1170
Change-Id: I9cf63ca52297cd45ea062ec7ddfb1ff4a9e853f7
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
import static org.opendaylight.netconf.client.mdsal.impl.NetconfMessageTransformUtil.IETF_NETCONF_MONITORING;
import static org.opendaylight.netconf.client.mdsal.impl.NetconfMessageTransformUtil.NETCONF_DATA_NODEID;
import static org.opendaylight.netconf.client.mdsal.impl.NetconfMessageTransformUtil.NETCONF_FILTER_NODEID;
-import static org.opendaylight.netconf.client.mdsal.impl.NetconfMessageTransformUtil.NETCONF_FILTER_QNAME;
import static org.opendaylight.netconf.client.mdsal.impl.NetconfMessageTransformUtil.NETCONF_GET_NODEID;
import static org.opendaylight.netconf.client.mdsal.impl.NetconfMessageTransformUtil.NETCONF_GET_QNAME;
-import static org.opendaylight.netconf.client.mdsal.impl.NetconfMessageTransformUtil.NETCONF_TYPE_QNAME;
import static org.opendaylight.netconf.client.mdsal.impl.NetconfMessageTransformUtil.toId;
import com.google.common.annotations.VisibleForTesting;
import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.mdsal.dom.api.DOMRpcResult;
import org.opendaylight.mdsal.dom.api.DOMRpcService;
+import org.opendaylight.netconf.api.NamespaceURN;
import org.opendaylight.netconf.api.xml.XmlUtil;
import org.opendaylight.netconf.client.mdsal.api.NetconfDeviceSchemas;
import org.opendaylight.netconf.client.mdsal.api.NetconfSessionPreferences;
static {
final Document document = XmlUtil.newDocument();
- final Element filterElem = XmlUtil.createElement(document, NETCONF_FILTER_QNAME.getLocalName(),
- Optional.of(NETCONF_FILTER_QNAME.getNamespace().toString()));
- filterElem.setAttributeNS(NETCONF_FILTER_QNAME.getNamespace().toString(), NETCONF_TYPE_QNAME.getLocalName(),
- "subtree");
+ final Element filterElem = XmlUtil.createElement(document, "filter", Optional.of(NamespaceURN.BASE));
+ filterElem.setAttribute("type", "subtree");
final Element stateElem = XmlUtil.createElement(document, NetconfState.QNAME.getLocalName(),
Optional.of(NetconfState.QNAME.getNamespace().toString()));
import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
import org.opendaylight.netconf.api.DocumentedException;
import org.opendaylight.netconf.api.EffectiveOperation;
+import org.opendaylight.netconf.api.NamespaceURN;
import org.opendaylight.netconf.api.messages.NetconfMessage;
import org.opendaylight.netconf.api.messages.NotificationMessage;
import org.opendaylight.netconf.api.messages.RpcMessage;
public static final @NonNull QName CREATE_SUBSCRIPTION_RPC_QNAME =
QName.create(CreateSubscriptionInput.QNAME, "create-subscription").intern();
- private static final String SUBTREE = "subtree";
// Blank document used for creation of new DOM nodes
private static final Document BLANK_DOCUMENT = XmlUtil.newDocument();
public static final @NonNull Absolute NETCONF_GET_CONFIG_PATH = toPath(NETCONF_GET_CONFIG_QNAME);
public static final @NonNull QName NETCONF_DISCARD_CHANGES_QNAME = QName.create(NETCONF_QNAME, "discard-changes");
public static final @NonNull Absolute NETCONF_DISCARD_CHANGES_PATH = toPath(NETCONF_DISCARD_CHANGES_QNAME);
- public static final @NonNull QName NETCONF_TYPE_QNAME = QName.create(NETCONF_QNAME, "type").intern();
- public static final @NonNull QName NETCONF_FILTER_QNAME = QName.create(NETCONF_QNAME, "filter").intern();
public static final @NonNull QName NETCONF_GET_QNAME =
QName.create(NETCONF_QNAME, XmlNetconfConstants.GET).intern();
public static final @NonNull NodeIdentifier NETCONF_GET_NODEID = NodeIdentifier.create(NETCONF_GET_QNAME);
public static final @NonNull Absolute CREATE_SUBSCRIPTION_RPC_PATH = toPath(CREATE_SUBSCRIPTION_RPC_QNAME);
- public static final @NonNull NodeIdentifier NETCONF_FILTER_NODEID = NodeIdentifier.create(NETCONF_FILTER_QNAME);
+ public static final @NonNull NodeIdentifier NETCONF_FILTER_NODEID =
+ NodeIdentifier.create(QName.create(NETCONF_QNAME, "filter").intern());
- public static final @NonNull AnyxmlNode<?> EMPTY_FILTER = buildFilterStructure(getNetconfFilterElement());
+ public static final @NonNull AnyxmlNode<?> EMPTY_FILTER = buildFilterStructure(newFilterElement());
private NetconfMessageTransformUtil() {
// Hidden on purpose
*/
public static AnyxmlNode<?> toFilterStructure(final YangInstanceIdentifier identifier,
final EffectiveModelContext ctx) {
- final Element element = getNetconfFilterElement();
+ final Element element = newFilterElement();
try {
NormalizedDataUtil.writeFilter(identifier, new DOMResult(element), ctx, null);
} catch (IOException | XMLStreamException e) {
public static AnyxmlNode<?> toFilterStructure(final List<FieldsFilter> fieldsFilters,
final EffectiveModelContext ctx) {
Preconditions.checkState(!fieldsFilters.isEmpty(), "An empty list of subtree filters is not allowed");
- final Element element = getNetconfFilterElement();
+ final Element element = newFilterElement();
for (final FieldsFilter filter : fieldsFilters) {
try {
return buildFilterStructure(element);
}
- private static Element getNetconfFilterElement() {
- final Element element = XmlUtil.createElement(BLANK_DOCUMENT, NETCONF_FILTER_QNAME.getLocalName(),
- Optional.of(NETCONF_FILTER_QNAME.getNamespace().toString()));
- element.setAttributeNS(NETCONF_FILTER_QNAME.getNamespace().toString(), NETCONF_TYPE_QNAME.getLocalName(),
- SUBTREE);
+ private static Element newFilterElement() {
+ final var element = XmlUtil.createElement(BLANK_DOCUMENT, "filter", Optional.of(NamespaceURN.BASE));
+ element.setAttribute("type", "subtree");
return element;
}
import static org.opendaylight.netconf.client.mdsal.impl.NetconfMessageTransformUtil.NETCONF_CONFIG_QNAME;
import static org.opendaylight.netconf.client.mdsal.impl.NetconfMessageTransformUtil.NETCONF_DATA_NODEID;
import static org.opendaylight.netconf.client.mdsal.impl.NetconfMessageTransformUtil.NETCONF_FILTER_NODEID;
-import static org.opendaylight.netconf.client.mdsal.impl.NetconfMessageTransformUtil.NETCONF_FILTER_QNAME;
import static org.opendaylight.netconf.client.mdsal.impl.NetconfMessageTransformUtil.NETCONF_OPERATION_QNAME;
import static org.opendaylight.netconf.common.mdsal.NormalizedDataUtil.NETCONF_DATA_QNAME;
import static org.opendaylight.netconf.common.mdsal.NormalizedDataUtil.appendListKeyNodes;
import javax.xml.transform.dom.DOMSource;
import org.opendaylight.netconf.api.DocumentedException;
import org.opendaylight.netconf.api.EffectiveOperation;
+import org.opendaylight.netconf.api.NamespaceURN;
import org.opendaylight.netconf.api.xml.XmlElement;
import org.opendaylight.netconf.api.xml.XmlUtil;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
}
private static Element prepareFilterElement(final Document document) {
- // FIXME: use a constant
- final var filterNs = NETCONF_FILTER_QNAME.getNamespace().toString();
- final var filter = document.createElementNS(filterNs, NETCONF_FILTER_QNAME.getLocalName());
- final var attr = document.createAttributeNS(filterNs, "type");
- attr.setTextContent("subtree");
- filter.setAttributeNode(attr);
+ final var filter = document.createElementNS(NamespaceURN.BASE, "filter");
+ filter.setAttribute("type", "subtree");
document.appendChild(filter);
return filter;
}
assertSimilarXml(netconfMessage, "<rpc message-id=\"m-0\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
+ "<get-config xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
- + "<filter xmlns:ns0=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ns0:type=\"subtree\">\n"
+ + "<filter type=\"subtree\">\n"
+ "<netconf-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring\">\n"
+ "<schemas>\n"
+ "<schema>\n"
assertSimilarXml(netconfMessage, "<rpc message-id=\"m-0\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
+ "<get-config xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
- + "<filter xmlns:ns0=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ns0:type=\"subtree\">\n"
+ + "<filter type=\"subtree\">\n"
+ "<netconf-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring\">\n"
+ "<schemas/>\n"
+ "</netconf-state>"
assertSimilarXml(netconfMessage, "<rpc message-id=\"m-0\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">"
+ "<get xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
- + "<filter xmlns:ns0=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ns0:type=\"subtree\">\n"
+ + "<filter type=\"subtree\">\n"
+ "<netconf-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring\">\n"
+ "<capabilities>\n"
+ "<capability>a:b:c</capability>\n"
assertSimilarXml(netconfMessage, "<rpc message-id=\"m-0\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
+ "<get>\n"
- + "<filter xmlns:ns0=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ns0:type=\"subtree\">\n"
+ + "<filter type=\"subtree\">\n"
+ "<netconf-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring\">\n"
+ "<capabilities>\n"
+ "<capability/>\n"
assertSimilarXml(netconfMessage, "<rpc message-id=\"m-0\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
+ "<get>\n"
- + "<filter xmlns:ns0=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ns0:type=\"subtree\">\n"
+ + "<filter type=\"subtree\">\n"
+ "<netconf-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring\">\n"
+ "<datastores>\n"
+ "<datastore/>\n"
// testing
assertSimilarXml(netconfMessage, "<rpc message-id=\"m-0\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
+ "<get>\n"
- + "<filter xmlns:ns0=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ns0:type=\"subtree\">\n"
+ + "<filter type=\"subtree\">\n"
+ "<netconf-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring\">\n"
+ "<statistics>\n"
+ "<netconf-start-time/>\n"
// testing
assertSimilarXml(netconfMessage, "<rpc message-id=\"m-0\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
+ "<get>\n"
- + "<filter xmlns:ns0=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ns0:type=\"subtree\">\n"
+ + "<filter type=\"subtree\">\n"
+ "<netconf-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring\">\n"
+ "<capabilities/>\n"
+ "<datastores/>\n"
// testing
assertSimilarXml(netconfMessage, "<rpc message-id=\"m-0\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
+ "<get>\n"
- + "<filter xmlns:ns0=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ns0:type=\"subtree\">\n"
+ + "<filter type=\"subtree\">\n"
+ "<netconf-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring\"/>\n"
+ "</filter>\n"
+ "</get>\n"
// testing
assertSimilarXml(netconfMessage, "<rpc message-id=\"m-0\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
+ "<get>\n"
- + "<filter xmlns:ns0=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ns0:type=\"subtree\">\n"
+ + "<filter type=\"subtree\">\n"
+ "<netconf-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring\">\n"
+ "<schemas>\n"
+ "<schema>\n"
// testing
assertSimilarXml(netconfMessage, "<rpc message-id=\"m-0\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
+ "<get>\n"
- + "<filter xmlns:ns0=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ns0:type=\"subtree\">\n"
+ + "<filter type=\"subtree\">\n"
+ "<netconf-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring\">\n"
+ "<datastores>\n"
+ "<datastore>\n"
// testing
assertSimilarXml(netconfMessage, "<rpc message-id=\"m-0\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
+ "<get>\n"
- + "<filter xmlns:ns0=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ns0:type=\"subtree\">\n"
+ + "<filter type=\"subtree\">\n"
+ "<netconf-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring\">\n"
+ "<datastores>\n"
+ "<datastore/>\n"
// testing
assertSimilarXml(netconfMessage, "<rpc message-id=\"m-0\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
+ "<get>\n"
- + "<filter xmlns:ns0=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ns0:type=\"subtree\">\n"
+ + "<filter type=\"subtree\">\n"
+ "<netconf-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring\">\n"
+ "<sessions>\n"
+ "<session>\n"
import static org.mockito.Mockito.verify;
import static org.opendaylight.netconf.client.mdsal.impl.NetconfMessageTransformUtil.DISCARD_CHANGES_RPC_CONTENT;
import static org.opendaylight.netconf.client.mdsal.impl.NetconfMessageTransformUtil.NETCONF_CANDIDATE_NODEID;
-import static org.opendaylight.netconf.client.mdsal.impl.NetconfMessageTransformUtil.NETCONF_FILTER_QNAME;
+import static org.opendaylight.netconf.client.mdsal.impl.NetconfMessageTransformUtil.NETCONF_FILTER_NODEID;
import static org.opendaylight.netconf.client.mdsal.impl.NetconfMessageTransformUtil.NETCONF_RUNNING_NODEID;
import com.google.common.util.concurrent.Futures;
public void testIgnoreNonVisibleData() {
final WriteCandidateTx tx = new WriteCandidateTx(id, new NetconfBaseOps(rpc, mock(MountPointContext.class)),
false);
- final MapNode emptyList = ImmutableNodes.mapNodeBuilder(NETCONF_FILTER_QNAME).build();
- tx.merge(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.of(NETCONF_FILTER_QNAME), emptyList);
- tx.put(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.of(NETCONF_FILTER_QNAME), emptyList);
+ final MapNode emptyList = ImmutableNodes.mapNodeBuilder(NETCONF_FILTER_NODEID).build();
+ tx.merge(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.of(NETCONF_FILTER_NODEID), emptyList);
+ tx.put(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.of(NETCONF_FILTER_NODEID), emptyList);
verify(rpc, atMost(1)).invokeNetconf(any(), any());
}
-<filter xmlns:ns0="urn:ietf:params:xml:ns:netconf:base:1.0" ns0:type="subtree" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+<filter xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" type="subtree">
<top xmlns="http://example.com/schema/1.2/config">
<users>
</users>
</top>
-</filter>
\ No newline at end of file
+</filter>
-<filter xmlns:ns0="urn:ietf:params:xml:ns:netconf:base:1.0" ns0:type="subtree" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+<filter xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" type="subtree">
<top xmlns="http://example.com/schema/1.2/config">
<users>
<user>
-<filter xmlns:ns0="urn:ietf:params:xml:ns:netconf:base:1.0" ns0:type="subtree" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+<filter xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" type="subtree">
<top xmlns="http://example.com/schema/1.2/config">
<users>
<user>
</user>
</users>
</top>
-</filter>
\ No newline at end of file
+</filter>
-<filter xmlns:ns0="urn:ietf:params:xml:ns:netconf:base:1.0" ns0:type="subtree" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+<filter xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" type="subtree">
<top xmlns="http://example.com/schema/1.2/config">
<users>
<user>
-<filter xmlns:ns0="urn:ietf:params:xml:ns:netconf:base:1.0" ns0:type="subtree"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+<filter xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" type="subtree">
<c-1 xmlns="test-namespace">
<leaf-1/>
<list-1>
</c-2>
</list-1>
</c-1>
-</filter>
\ No newline at end of file
+</filter>
-<filter xmlns:ns0="urn:ietf:params:xml:ns:netconf:base:1.0" ns0:type="subtree"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+<filter xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" type="subtree">
<c-1 xmlns="test-namespace">
<list-1>
<c-2/>
<c-x xmlns="test-namespace">
<l-x/>
</c-x>
-</filter>
\ No newline at end of file
+</filter>
<source>
<running/>
</source>
- <filter xmlns:ns0="urn:ietf:params:xml:ns:netconf:base:1.0" ns0:type="subtree">
+ <filter type="subtree">
<c xmlns="test:namespace">
<a/>
<b/>
</c>
</filter>
</get-config>
-</rpc>
\ No newline at end of file
+</rpc>
<source>
<running/>
</source>
- <filter xmlns:ns0="urn:ietf:params:xml:ns:netconf:base:1.0" ns0:type="subtree">
+ <filter type="subtree">
<c xmlns="test:namespace">
<a/>
<d>
</e>
</filter>
</get-config>
-</rpc>
\ No newline at end of file
+</rpc>
<rpc message-id="m-0" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<get>
- <filter xmlns:ns0="urn:ietf:params:xml:ns:netconf:base:1.0" ns0:type="subtree">
+ <filter type="subtree">
<c xmlns="test:namespace">
<a/>
<b/>
</c>
</filter>
</get>
-</rpc>
\ No newline at end of file
+</rpc>
<rpc message-id="m-0" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<get>
- <filter xmlns:ns0="urn:ietf:params:xml:ns:netconf:base:1.0" ns0:type="subtree">
+ <filter type="subtree">
<c xmlns="test:namespace"/>
<e xmlns="test:namespace"/>
</filter>
</get>
-</rpc>
\ No newline at end of file
+</rpc>
<rpc message-id="m-0" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<get>
- <filter xmlns:ns0="urn:ietf:params:xml:ns:netconf:base:1.0" ns0:type="subtree">
+ <filter type="subtree">
<c xmlns="test:namespace">
<a/>
<d>
</e>
</filter>
</get>
-</rpc>
\ No newline at end of file
+</rpc>
<source>
<candidate/>
</source>
- <filter xmlns:ns0="urn:ietf:params:xml:ns:netconf:base:1.0" ns0:type="subtree">
+ <filter type="subtree">
<c xmlns="test:namespace"/>
</filter>
</get-config>
-</rpc>
\ No newline at end of file
+</rpc>
<source>
<running/>
</source>
- <filter xmlns:a="urn:ietf:params:xml:ns:netconf:base:1.0" a:type="subtree">
+ <filter type="subtree">
<modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
<module>
<type xmlns:x="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">x:sal-netconf-connector</type>
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="m-10">
<get-config>
- <filter xmlns:ns0="urn:ietf:params:xml:ns:netconf:base:1.0" ns0:type="subtree">
+ <filter type="subtree">
<services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
<service/>
</services>