Migrate netconf components to the new XML parser from YANG tools.
Change-Id: I42899d4d07cb2f917c50fa862cd6453bb0a8764d
Signed-off-by: Igor Foltin <igor.foltin@pantheon.tech>
import com.google.common.base.Throwables;
import com.google.common.util.concurrent.CheckedFuture;
import java.io.IOException;
+import java.io.StringReader;
import java.net.URI;
import java.util.Collection;
import java.util.Collections;
import org.opendaylight.controller.md.sal.dom.api.DOMRpcException;
import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
+import org.opendaylight.netconf.api.NetconfDocumentedException;
import org.opendaylight.netconf.api.xml.XmlNetconfConstants;
import org.opendaylight.netconf.mapping.api.HandlingPriority;
import org.opendaylight.netconf.mapping.api.NetconfOperationChainedExecution;
import org.opendaylight.netconf.mdsal.connector.CurrentSchemaContext;
import org.opendaylight.netconf.util.mapping.AbstractSingletonNetconfOperation;
+import org.opendaylight.yangtools.util.xml.UntrustedXML;
import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
import org.opendaylight.yangtools.yang.data.codec.xml.XMLStreamNormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.codec.xml.XmlParserStream;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult;
import org.opendaylight.yangtools.yang.data.impl.schema.SchemaOrderedNormalizedNodeWriter;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.DomUtils;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser.DomToNormalizedNodeParserFactory;
import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
* @param input input container schema node, or null if rpc does not take any input
* @return parsed rpc into normalized node, or null if input schema is null
*/
+ @SuppressWarnings("checkstyle:IllegalCatch")
@Nullable
- private NormalizedNode<?, ?> rpcToNNode(final XmlElement element, @Nullable final ContainerSchemaNode input) {
- return input.getChildNodes().isEmpty() ? null : DomToNormalizedNodeParserFactory
- .getInstance(DomUtils.defaultValueCodecProvider(), schemaContext.getCurrentContext())
- .getContainerNodeParser()
- .parse(Collections.singletonList(element.getDomElement()), input);
+ private NormalizedNode<?, ?> rpcToNNode(final XmlElement element, @Nullable final ContainerSchemaNode input)
+ throws DocumentedException {
+ if (input.getChildNodes().isEmpty()) {
+ return null;
+ }
+
+ final NormalizedNodeResult resultHolder = new NormalizedNodeResult();
+ final NormalizedNodeStreamWriter writer = ImmutableNormalizedNodeStreamWriter.from(resultHolder);
+ final XmlParserStream xmlParser = XmlParserStream.create(writer, schemaContext.getCurrentContext(), input);
+
+ try {
+ xmlParser.parse(UntrustedXML.createXMLStreamReader(new StringReader(XmlUtil.toString(element))));
+ } catch (final Exception ex) {
+ throw new NetconfDocumentedException("Error parsing input: " + ex.getMessage(), ex, ErrorType.PROTOCOL,
+ ErrorTag.MALFORMED_MESSAGE, ErrorSeverity.ERROR);
+ }
+
+ return resultHolder.getResult();
}
}
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
-import java.io.StringWriter;
+import java.io.StringReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URI;
import java.util.concurrent.ExecutionException;
import java.util.regex.Pattern;
import javax.xml.parsers.DocumentBuilder;
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
import org.opendaylight.controller.config.util.xml.XmlUtil;
import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
import org.opendaylight.mdsal.binding.generator.impl.ModuleInfoBackedContext;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
import org.opendaylight.yangtools.yang.data.codec.gson.JsonParserStream;
-import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlUtils;
+import org.opendaylight.yangtools.yang.data.codec.xml.XmlParserStream;
import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser.DomToNormalizedNodeParserFactory;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier;
import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
-import org.xml.sax.SAXException;
/**
* Holds URLs with YANG schema resources for all yang modules reported in
? Optional.of(resultHolder.getResult()) : Optional.<NormalizedNode<?, ?>>absent();
}
+ @SuppressWarnings("checkstyle:IllegalCatch")
private static Optional<NormalizedNode<?, ?>> readXml(final InputStream in) {
- final DomToNormalizedNodeParserFactory parserFactory =
- DomToNormalizedNodeParserFactory.getInstance(XmlUtils.DEFAULT_XML_CODEC_PROVIDER, LIBRARY_CONTEXT);
try {
final DocumentBuilder docBuilder = UntrustedXML.newDocumentBuilder();
}
}
- final Transformer transformer = TransformerFactory.newInstance().newTransformer();
- final StringWriter sw = new StringWriter();
- transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
- transformer.transform(new DOMSource(doc), new StreamResult(sw));
- final NormalizedNode<?, ?> parsed =
- parserFactory.getContainerNodeParser()
- .parse(Collections.singleton(XmlUtil.readXmlToElement(sw.toString())),
- (ContainerSchemaNode) LIBRARY_CONTEXT.getDataChildByName(ModulesState.QNAME));
+ final NormalizedNodeResult resultHolder = new NormalizedNodeResult();
+ final NormalizedNodeStreamWriter writer = ImmutableNormalizedNodeStreamWriter.from(resultHolder);
+ final XmlParserStream xmlParser = XmlParserStream.create(writer, LIBRARY_CONTEXT,
+ LIBRARY_CONTEXT.getDataChildByName(ModulesState.QNAME));
+
+ xmlParser.parse(UntrustedXML.createXMLStreamReader(new StringReader(XmlUtil.toString(
+ doc.getDocumentElement(), false))));
+ final NormalizedNode<?, ?> parsed = resultHolder.getResult();
return Optional.of(parsed);
- } catch (final SAXException | IOException | TransformerException e) {
+ } catch (final Exception e) {
LOG.warn("Unable to parse yang library xml content", e);
}
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import java.io.IOException;
+import java.io.StringReader;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import javax.xml.transform.dom.DOMResult;
import org.opendaylight.controller.config.util.xml.MissingNameSpaceException;
import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
import org.opendaylight.controller.md.sal.dom.api.DOMEvent;
import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
import org.opendaylight.netconf.sal.connect.api.MessageTransformer;
import org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil;
import org.opendaylight.netconf.sal.connect.util.MessageCounter;
+import org.opendaylight.yangtools.util.xml.UntrustedXML;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlUtils;
+import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.codec.xml.XmlParserStream;
import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser.DomToNormalizedNodeParserFactory;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult;
import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
private final MessageCounter counter;
private final Map<QName, RpcDefinition> mappedRpcs;
private final Multimap<QName, NotificationDefinition> mappedNotifications;
- private final DomToNormalizedNodeParserFactory parserFactory;
+
+ private final boolean strictParsing;
public NetconfMessageTransformer(final SchemaContext schemaContext, final boolean strictParsing) {
this(schemaContext, strictParsing, BaseSchema.BASE_NETCONF_CTX);
final BaseSchema baseSchema) {
this.counter = new MessageCounter();
this.schemaContext = schemaContext;
- parserFactory = DomToNormalizedNodeParserFactory
- .getInstance(XmlUtils.DEFAULT_XML_CODEC_PROVIDER, schemaContext, strictParsing);
mappedRpcs = Maps.uniqueIndex(schemaContext.getOperations(), SchemaNode::getQName);
mappedNotifications = Multimaps.index(schemaContext.getNotifications(),
node -> node.getQName().withoutRevision());
this.baseSchema = baseSchema;
+ this.strictParsing = strictParsing;
}
+ @SuppressWarnings("checkstyle:IllegalCatch")
@Override
public synchronized DOMNotification toNotification(final NetconfMessage message) {
final Map.Entry<Date, XmlElement> stripped = NetconfMessageTransformUtil.stripNotification(message);
final Element element = stripped.getValue().getDomElement();
final ContainerNode content;
try {
- content = parserFactory.getContainerNodeParser().parse(Collections.singleton(element),
- notificationAsContainerSchemaNode);
- } catch (IllegalArgumentException e) {
+ final NormalizedNodeResult resultHolder = new NormalizedNodeResult();
+ final NormalizedNodeStreamWriter writer = ImmutableNormalizedNodeStreamWriter.from(resultHolder);
+ final XmlParserStream xmlParser = XmlParserStream.create(writer, schemaContext,
+ notificationAsContainerSchemaNode, strictParsing);
+
+ xmlParser.parse(UntrustedXML.createXMLStreamReader(new StringReader(XmlUtil.toString(element))));
+ content = (ContainerNode) resultHolder.getResult();
+ } catch (final Exception e) {
throw new IllegalArgumentException(String.format("Failed to parse notification %s", element), e);
}
return new NetconfDeviceNotification(content, stripped.getKey());
|| rpc.getNamespace().equals(NetconfMessageTransformUtil.CREATE_SUBSCRIPTION_RPC_QNAME.getNamespace());
}
-
+ @SuppressWarnings("checkstyle:IllegalCatch")
@Override
public synchronized DOMRpcResult toRpcResult(final NetconfMessage message, final SchemaPath rpc) {
final NormalizedNode<?, ?> normalizedNode;
final ContainerNode dataNode;
try {
- dataNode =
- parserFactory.getContainerNodeParser().parse(Collections.singleton(xmlData), schemaForDataRead);
- } catch (IllegalArgumentException e) {
+ final NormalizedNodeResult resultHolder = new NormalizedNodeResult();
+ final NormalizedNodeStreamWriter writer = ImmutableNormalizedNodeStreamWriter.from(resultHolder);
+ final XmlParserStream xmlParser = XmlParserStream.create(writer, schemaContext, schemaForDataRead,
+ strictParsing);
+
+ xmlParser.parse(UntrustedXML.createXMLStreamReader(new StringReader(XmlUtil.toString(xmlData))));
+ dataNode = (ContainerNode) resultHolder.getResult();
+ } catch (final Exception e) {
throw new IllegalArgumentException(String.format("Failed to parse data response %s", xmlData), e);
}
} else {
final Element element = message.getDocument().getDocumentElement();
try {
- normalizedNode = parserFactory.getContainerNodeParser().parse(Collections.singleton(element),
- rpcDefinition.getOutput());
- } catch (IllegalArgumentException e) {
+ final NormalizedNodeResult resultHolder = new NormalizedNodeResult();
+ final NormalizedNodeStreamWriter writer = ImmutableNormalizedNodeStreamWriter.from(resultHolder);
+ final XmlParserStream xmlParser = XmlParserStream.create(writer, schemaContext,
+ rpcDefinition.getOutput(), strictParsing);
+
+ xmlParser.parse(UntrustedXML.createXMLStreamReader(new StringReader(XmlUtil.toString(element))));
+ normalizedNode = resultHolder.getResult();
+ } catch (final Exception e) {
throw new IllegalArgumentException(String.format("Failed to parse RPC response %s", element), e);
}
}
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.opendaylight.controller.md.sal.dom.api.DOMRpcException;
import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementationNotAvailableException;
import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfState;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Schemas;
+import org.opendaylight.yangtools.util.xml.UntrustedXML;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.RpcError;
import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlUtils;
+import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.codec.xml.XmlParserStream;
import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.ToNormalizedNodeParser;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser.DomToNormalizedNodeParserFactory;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult;
import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
public class NetconfStateSchemasTest {
final DataSchemaNode schemasNode =
((ContainerSchemaNode) schemaContext
.getDataChildByName(NetconfState.QNAME)).getDataChildByName(Schemas.QNAME);
- final Document schemasXml =
- XmlUtil.readXmlToDocument(getClass().getResourceAsStream("/netconf-state.schemas.payload.xml"));
- final ToNormalizedNodeParser<Element, ContainerNode, ContainerSchemaNode> containerNodeParser =
- DomToNormalizedNodeParserFactory
- .getInstance(XmlUtils.DEFAULT_XML_CODEC_PROVIDER, schemaContext, false).getContainerNodeParser();
- compositeNodeSchemas = containerNodeParser
- .parse(Collections.singleton(schemasXml.getDocumentElement()), (ContainerSchemaNode) schemasNode);
+
+ final NormalizedNodeResult resultHolder = new NormalizedNodeResult();
+ final NormalizedNodeStreamWriter writer = ImmutableNormalizedNodeStreamWriter.from(resultHolder);
+ final XmlParserStream xmlParser = XmlParserStream.create(writer, schemaContext, schemasNode, false);
+
+ xmlParser.parse(UntrustedXML.createXMLStreamReader(getClass().getResourceAsStream(
+ "/netconf-state.schemas.payload.xml")));
+ compositeNodeSchemas = (ContainerNode) resultHolder.getResult();
}
return context;
}
- @Test(expected = IllegalStateException.class)
+ @Test(expected = IllegalArgumentException.class)
public void testMostRecentWrongYangModel() throws Exception {
final SchemaContext schemaContext = getNotificationSchemaContext(getClass(), true);
messageTransformer = new NetconfMessageTransformer(schemaContext, true);
import com.google.common.base.Optional;
import java.io.IOException;
+import java.io.StringReader;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
import org.opendaylight.netconf.cli.io.BaseConsoleContext;
import org.opendaylight.netconf.cli.io.ConsoleContext;
import org.opendaylight.netconf.cli.io.ConsoleIO;
import org.opendaylight.netconf.cli.reader.AbstractReader;
import org.opendaylight.netconf.cli.reader.ReadingException;
+import org.opendaylight.yangtools.util.xml.UntrustedXML;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.codec.xml.XmlParserStream;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.DomUtils;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser.DomToNormalizedNodeParserFactory;
import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.w3c.dom.Document;
-import org.xml.sax.SAXException;
public class AnyXmlReader extends AbstractReader<AnyXmlSchemaNode> {
return newNodes;
}
+ @SuppressWarnings("checkstyle:IllegalCatch")
private Optional<DataContainerChild<?, ?>> tryParse(final String rawValue, final AnyXmlSchemaNode schemaNode) {
try {
- final Document dom = XmlUtil.readXmlToDocument(rawValue);
- return Optional.of(
- DomToNormalizedNodeParserFactory
- .getInstance(DomUtils.defaultValueCodecProvider(), getSchemaContext())
- .getAnyXmlNodeParser()
- .parse(Collections.singletonList(dom.getDocumentElement()), schemaNode)
- );
- } catch (SAXException | IOException e) {
+ final NormalizedNodeResult resultHolder = new NormalizedNodeResult();
+ final NormalizedNodeStreamWriter writer = ImmutableNormalizedNodeStreamWriter.from(resultHolder);
+ final XmlParserStream xmlParser = XmlParserStream.create(writer, getSchemaContext(), schemaNode);
+
+ xmlParser.parse(UntrustedXML.createXMLStreamReader(new StringReader(rawValue)));
+ return Optional.of((DataContainerChild<?, ?>) resultHolder.getResult());
+ } catch (final Exception e) {
// TODO log
return Optional.absent();
}