import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import javax.xml.stream.XMLStreamException;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
private NormalizedNode<?, ?> parseResult(final NetconfMessage message,
final OperationDefinition operationDefinition) {
+ final Optional<XmlElement> okResponseElement = XmlElement.fromDomDocument(message.getDocument())
+ .getOnlyChildElementWithSameNamespaceOptionally("ok");
if (operationDefinition.getOutput().getChildNodes().isEmpty()) {
- Preconditions.checkArgument(XmlElement.fromDomDocument(
- message.getDocument()).getOnlyChildElementWithSameNamespaceOptionally("ok").isPresent(),
+ Preconditions.checkArgument(okResponseElement.isPresent(),
"Unexpected content in response of rpc: %s, %s", operationDefinition.getQName(), message);
return null;
} else {
- final Element element = message.getDocument().getDocumentElement();
+ if (okResponseElement.isPresent()) {
+ LOG.debug("Received response <ok/> for RPC with defined Output");
+ return null;
+ }
+
+ Element element = message.getDocument().getDocumentElement();
try {
final NormalizedNodeResult resultHolder = new NormalizedNodeResult();
final NormalizedNodeStreamWriter writer = ImmutableNormalizedNodeStreamWriter.from(resultHolder);
package org.opendaylight.netconf.sal.connect.netconf.schema.mapping;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
private static final String URN_EXAMPLE_AUGMENTED_ACTION = "urn:example:augmented-action";
+ private static final String URN_EXAMPLE_RPCS_ACTIONS_OUTPUTS = "urn:example:rpcs-actions-outputs";
+
private static final QName SERVER_QNAME =
QName.create(URN_EXAMPLE_SERVER_FARM, REVISION_EXAMPLE_SERVER_FARM, "server");
private static final QName RESET_QNAME = QName.create(SERVER_QNAME, "reset");
private static final SchemaPath DISABLE_INTERFACE_PATH =
SchemaPath.create(true, DEVICE_QNAME, INTERFACE_QNAME, DISABLE_QNAME);
+ private static final QName CHECK_WITH_OUTPUT_QNAME =
+ QName.create(URN_EXAMPLE_RPCS_ACTIONS_OUTPUTS, "check-with-output");
+ private static final SchemaPath CHECK_WITH_OUTPUT_INTERFACE_PATH =
+ SchemaPath.create(true, DEVICE_QNAME, INTERFACE_QNAME, CHECK_WITH_OUTPUT_QNAME);
+ private static final QName CHECK_WITHOUT_OUTPUT_QNAME =
+ QName.create(URN_EXAMPLE_RPCS_ACTIONS_OUTPUTS, "check-without-output");
+ private static final SchemaPath CHECK_WITHOUT_OUTPUT_INTERFACE_PATH =
+ SchemaPath.create(true, DEVICE_QNAME, INTERFACE_QNAME, CHECK_WITHOUT_OUTPUT_QNAME);
+ private static final QName RPC_WITH_OUTPUT_QNAME =
+ QName.create(URN_EXAMPLE_RPCS_ACTIONS_OUTPUTS, "rpc-with-output");
+ private static final QName RPC_WITHOUT_OUTPUT_QNAME =
+ QName.create(URN_EXAMPLE_RPCS_ACTIONS_OUTPUTS, "rpc-without-output");
+
private static final QName BOX_OUT_QNAME =
QName.create(URN_EXAMPLE_SERVER_FARM, REVISION_EXAMPLE_SERVER_FARM, "box-out");
private static final QName BOX_IN_QNAME = QName.create(BOX_OUT_QNAME, "box-in");
ACTION_SCHEMA = YangParserTestUtils.parseYangResources(NetconfMessageTransformerTest.class,
"/schemas/example-server-farm.yang","/schemas/example-server-farm-2.yang",
- "/schemas/conflicting-actions.yang", "/schemas/augmented-action.yang");
+ "/schemas/conflicting-actions.yang", "/schemas/augmented-action.yang",
+ "/schemas/rpcs-actions-outputs.yang");
}
@AfterClass
transformer.toRpcResult(new NetconfMessage(XmlUtil.readXmlToDocument(result)), toPath(NETCONF_LOCK_QNAME));
}
+ @Test
+ public void testRpcEmptyBodyWithOutputDefinedSchemaResult() throws Exception {
+ final String result = "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><ok/></rpc-reply>";
+
+ DOMRpcResult domRpcResult = actionNetconfMessageTransformer
+ .toRpcResult(new NetconfMessage(XmlUtil.readXmlToDocument(result)),
+ toPath(RPC_WITH_OUTPUT_QNAME));
+ assertNotNull(domRpcResult);
+ }
+
+ @Test
+ public void testRpcEmptyBodyWithoutOutputDefinedSchemaResult() throws Exception {
+ final String result = "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><ok/></rpc-reply>";
+
+ DOMRpcResult domRpcResult = actionNetconfMessageTransformer
+ .toRpcResult(new NetconfMessage(XmlUtil.readXmlToDocument(result)),
+ toPath(RPC_WITHOUT_OUTPUT_QNAME));
+ assertNotNull(domRpcResult);
+ }
+
@Test
public void testDiscardChangesRequest() throws Exception {
final NetconfMessage netconfMessage =
schemaPaths.add(XYZZY_BAR_PATH);
schemaPaths.add(CHOICE_ACTION_PATH);
schemaPaths.add(DISABLE_INTERFACE_PATH);
+ schemaPaths.add(CHECK_WITH_OUTPUT_INTERFACE_PATH);
+ schemaPaths.add(CHECK_WITHOUT_OUTPUT_INTERFACE_PATH);
List<ActionDefinition> actions = NetconfMessageTransformer.getActions(ACTION_SCHEMA);
assertEquals(schemaPaths.size(), actions.size());
assertEquals("now", leaf.getValue());
}
+ @Test
+ public void toActionEmptyBodyWithOutputDefinedResultTest() throws Exception {
+ NetconfMessage message = new NetconfMessage(XmlUtil.readXmlToDocument(
+ "<rpc-reply message-id=\"101\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">"
+ + "<ok/>"
+ + "</rpc-reply>"));
+ DOMActionResult actionResult =
+ actionNetconfMessageTransformer.toActionResult(CHECK_WITH_OUTPUT_INTERFACE_PATH, message);
+ assertNotNull(actionResult);
+ assertFalse(actionResult.getOutput().isPresent());
+ }
+
+ @Test
+ public void toActionEmptyBodyWithoutOutputDefinedResultTest() throws Exception {
+ NetconfMessage message = new NetconfMessage(XmlUtil.readXmlToDocument(
+ "<rpc-reply message-id=\"101\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">"
+ + "<ok/>"
+ + "</rpc-reply>"));
+ DOMActionResult actionResult =
+ actionNetconfMessageTransformer.toActionResult(CHECK_WITHOUT_OUTPUT_INTERFACE_PATH, message);
+ assertNotNull(actionResult);
+ assertFalse(actionResult.getOutput().isPresent());
+ }
+
private static void checkAction(final QName actionQname, final Node action , final String inputLocalName,
final String inputNodeName, final String inputValue) {
checkNode(action, actionQname.getLocalName(), actionQname.getLocalName(),