Integrate netconf-mapping-api into netconf-server
[netconf.git] / protocol / netconf-server / src / main / java / org / opendaylight / netconf / server / api / operations / AbstractNetconfOperation.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.netconf.server.api.operations;
9
10 import java.util.Map;
11 import java.util.Optional;
12 import org.opendaylight.netconf.api.DocumentedException;
13 import org.opendaylight.netconf.api.xml.XmlElement;
14 import org.opendaylight.netconf.api.xml.XmlNetconfConstants;
15 import org.opendaylight.netconf.api.xml.XmlUtil;
16 import org.w3c.dom.Attr;
17 import org.w3c.dom.Document;
18 import org.w3c.dom.Element;
19 import org.w3c.dom.NodeList;
20
21 public abstract class AbstractNetconfOperation implements NetconfOperation {
22     private final String netconfSessionIdForReporting;
23
24     protected AbstractNetconfOperation(final String netconfSessionIdForReporting) {
25         this.netconfSessionIdForReporting = netconfSessionIdForReporting;
26     }
27
28     public final String getNetconfSessionIdForReporting() {
29         return netconfSessionIdForReporting;
30     }
31
32     @Override
33     public HandlingPriority canHandle(final Document message) throws DocumentedException {
34         OperationNameAndNamespace operationNameAndNamespace = null;
35         operationNameAndNamespace = new OperationNameAndNamespace(message);
36         return canHandle(operationNameAndNamespace.getOperationName(), operationNameAndNamespace.getNamespace());
37     }
38
39     protected HandlingPriority canHandle(final String operationName, final String operationNamespace) {
40         return operationName.equals(getOperationName()) && operationNamespace.equals(getOperationNamespace())
41                 ? getHandlingPriority()
42                 : HandlingPriority.CANNOT_HANDLE;
43     }
44
45     public static final class OperationNameAndNamespace {
46         private final String operationName;
47         private final String namespace;
48         private final XmlElement operationElement;
49
50         public OperationNameAndNamespace(final Document message) throws DocumentedException {
51             final var requestElement = getRequestElementWithCheck(message);
52             operationElement = requestElement.getOnlyChildElement();
53             operationName = operationElement.getName();
54             namespace = operationElement.getNamespace();
55         }
56
57         public String getOperationName() {
58             return operationName;
59         }
60
61         public String getNamespace() {
62             return namespace;
63         }
64
65         public XmlElement getOperationElement() {
66             return operationElement;
67         }
68     }
69
70     protected static XmlElement getRequestElementWithCheck(final Document message) throws DocumentedException {
71         return XmlElement.fromDomElementWithExpected(message.getDocumentElement(), XmlNetconfConstants.RPC_KEY,
72                 XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
73     }
74
75     protected HandlingPriority getHandlingPriority() {
76         return HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY;
77     }
78
79     protected String getOperationNamespace() {
80         return XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0;
81     }
82
83     protected abstract String getOperationName();
84
85     @Override
86     public Document handle(final Document requestMessage,
87             final NetconfOperationChainedExecution subsequentOperation) throws DocumentedException {
88
89         XmlElement requestElement = getRequestElementWithCheck(requestMessage);
90
91         Document document = XmlUtil.newDocument();
92
93         XmlElement operationElement = requestElement.getOnlyChildElement();
94         Map<String, Attr> attributes = requestElement.getAttributes();
95
96         Element response = handle(document, operationElement, subsequentOperation);
97         Element rpcReply = XmlUtil.createElement(document, XmlNetconfConstants.RPC_REPLY_KEY,
98                 Optional.of(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0));
99
100         if (XmlElement.fromDomElement(response).hasNamespace()) {
101             rpcReply.appendChild(response);
102         } else {
103             Element responseNS = XmlUtil.createElement(document, response.getNodeName(),
104                     Optional.of(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0));
105             NodeList list = response.getChildNodes();
106             while (list.getLength() != 0) {
107                 responseNS.appendChild(list.item(0));
108             }
109             rpcReply.appendChild(responseNS);
110         }
111
112         for (Attr attribute : attributes.values()) {
113             rpcReply.setAttributeNode((Attr) document.importNode(attribute, true));
114         }
115         document.appendChild(rpcReply);
116         return document;
117     }
118
119     protected abstract Element handle(Document document, XmlElement message,
120                                       NetconfOperationChainedExecution subsequentOperation)
121             throws DocumentedException;
122
123     @Override
124     public String toString() {
125         final StringBuilder sb = new StringBuilder(getClass().getName());
126         try {
127             sb.append("{name=").append(getOperationName());
128         } catch (UnsupportedOperationException e) {
129             // no problem
130         }
131         sb.append(", namespace=").append(getOperationNamespace());
132         sb.append(", session=").append(netconfSessionIdForReporting);
133         sb.append('}');
134         return sb.toString();
135     }
136 }