2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.controller.netconf.mdsal.connector.ops.get;
11 import com.google.common.base.Function;
12 import com.google.common.base.Throwables;
13 import com.google.common.collect.Iterables;
14 import java.io.IOException;
15 import javax.xml.stream.XMLOutputFactory;
16 import javax.xml.stream.XMLStreamException;
17 import javax.xml.stream.XMLStreamWriter;
18 import javax.xml.transform.dom.DOMResult;
19 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
20 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
21 import org.opendaylight.controller.netconf.mdsal.connector.CurrentSchemaContext;
22 import org.opendaylight.controller.netconf.mdsal.connector.ops.Datastore;
23 import org.opendaylight.controller.netconf.util.mapping.AbstractLastNetconfOperation;
24 import org.opendaylight.controller.netconf.util.xml.XmlElement;
25 import org.opendaylight.yangtools.yang.common.QName;
26 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
27 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
28 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
29 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
30 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
31 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
32 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
33 import org.opendaylight.yangtools.yang.data.impl.codec.xml.XMLStreamNormalizedNodeStreamWriter;
34 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
35 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
36 import org.w3c.dom.Document;
37 import org.w3c.dom.Node;
39 public abstract class AbstractGet extends AbstractLastNetconfOperation {
41 protected static final YangInstanceIdentifier ROOT = YangInstanceIdentifier.builder().build();
43 protected final CurrentSchemaContext schemaContext;
46 public AbstractGet(final String netconfSessionIdForReporting, final CurrentSchemaContext schemaContext) {
47 super(netconfSessionIdForReporting);
48 this.schemaContext = schemaContext;
51 private static final XMLOutputFactory XML_OUTPUT_FACTORY;
54 XML_OUTPUT_FACTORY = XMLOutputFactory.newFactory();
55 XML_OUTPUT_FACTORY.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, true);
58 protected Node transformNormalizedNode(final Document document, final NormalizedNode<?, ?> data, final YangInstanceIdentifier dataRoot) {
59 // boolean isDataRoot = true;
61 final DOMResult result = new DOMResult(document.createElement(XmlNetconfConstants.DATA_KEY));
63 final XMLStreamWriter xmlWriter = getXmlStreamWriter(result);
65 final NormalizedNodeStreamWriter nnStreamWriter = XMLStreamNormalizedNodeStreamWriter.create(xmlWriter,
66 schemaContext.getCurrentContext(), getSchemaPath(dataRoot));
68 final NormalizedNodeWriter nnWriter = NormalizedNodeWriter.forStreamWriter(nnStreamWriter);
71 writeRootElement(xmlWriter, nnWriter, (ContainerNode) data);
73 // if (data instanceof MapEntryNode) {
74 // // Restconf allows returning one list item. We need to wrap it
75 // // in map node in order to serialize it properly
76 // data = ImmutableNodes.mapNodeBuilder(data.getNodeType()).addChild((MapEntryNode) data).build();
78 // nnWriter.write(data);
81 return result.getNode();
84 private XMLStreamWriter getXmlStreamWriter(final DOMResult result) {
86 return XML_OUTPUT_FACTORY.createXMLStreamWriter(result);
87 } catch (final XMLStreamException e) {
88 throw new RuntimeException(e);
92 private static final Function<PathArgument, QName> PATH_ARG_TO_QNAME = new Function<YangInstanceIdentifier.PathArgument, QName>() {
94 public QName apply(final YangInstanceIdentifier.PathArgument input) {
95 return input.getNodeType();
99 private SchemaPath getSchemaPath(final YangInstanceIdentifier dataRoot) {
100 return SchemaPath.create(Iterables.transform(dataRoot.getPathArguments(), PATH_ARG_TO_QNAME), dataRoot.equals(ROOT));
103 // TODO this code is located in Restconf already
104 private void writeRootElement(final XMLStreamWriter xmlWriter, final NormalizedNodeWriter nnWriter, final ContainerNode data) {
106 final QName name = SchemaContext.NAME;
107 for (final DataContainerChild<? extends PathArgument, ?> child : data.getValue()) {
108 nnWriter.write(child);
112 } catch (XMLStreamException | IOException e) {
113 Throwables.propagate(e);
117 protected static final class GetConfigExecution {
118 private final Datastore datastore;
120 public GetConfigExecution(final Datastore datastore) {
121 this.datastore = datastore;
124 public Datastore getDatastore() {
128 static GetConfigExecution fromXml(final XmlElement xml, final String operationName) throws NetconfDocumentedException {
130 validateInputRpc(xml, operationName);
131 } catch (final NetconfDocumentedException e) {
132 throw new NetconfDocumentedException("Incorrect RPC: " + e.getMessage(), e.getErrorType(), e.getErrorTag(), e.getErrorSeverity(), e.getErrorInfo());
135 final Datastore sourceDatastore;
137 sourceDatastore = parseSource(xml);
138 } catch (final NetconfDocumentedException e) {
139 throw new NetconfDocumentedException("Get-config source attribute error: " + e.getMessage(), e.getErrorType(), e.getErrorTag(), e.getErrorSeverity(), e.getErrorInfo());
144 return new GetConfigExecution(sourceDatastore);
147 private static Datastore parseSource(final XmlElement xml) throws NetconfDocumentedException {
148 final Datastore sourceDatastore;
149 final XmlElement sourceElement = xml.getOnlyChildElement(XmlNetconfConstants.SOURCE_KEY,
150 XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
152 final String sourceParsed = sourceElement.getOnlyChildElement().getName();
153 sourceDatastore = Datastore.valueOf(sourceParsed);
154 return sourceDatastore;
157 private static void validateInputRpc(final XmlElement xml, String operationName) throws NetconfDocumentedException{
158 xml.checkName(operationName);
159 xml.checkNamespace(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);