2 * Copyright (c) 2013 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
8 package org.opendaylight.netconf.server.api.operations;
10 import static java.util.Objects.requireNonNull;
12 import org.eclipse.jdt.annotation.NonNull;
13 import org.opendaylight.netconf.api.DocumentedException;
14 import org.opendaylight.netconf.api.NamespaceURN;
15 import org.opendaylight.netconf.api.messages.RpcMessage;
16 import org.opendaylight.netconf.api.messages.RpcReplyMessage;
17 import org.opendaylight.netconf.api.xml.XmlElement;
18 import org.opendaylight.netconf.api.xml.XmlUtil;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.SessionIdType;
20 import org.w3c.dom.Attr;
21 import org.w3c.dom.Document;
22 import org.w3c.dom.Element;
24 public abstract class AbstractNetconfOperation implements NetconfOperation {
25 private final @NonNull SessionIdType sessionId;
27 protected AbstractNetconfOperation(final SessionIdType sessionId) {
28 this.sessionId = requireNonNull(sessionId);
31 public final @NonNull SessionIdType sessionId() {
36 public final HandlingPriority canHandle(final Document message) throws DocumentedException {
37 final var operationNameAndNamespace = new OperationNameAndNamespace(message);
38 return canHandle(operationNameAndNamespace.getOperationName(), operationNameAndNamespace.getNamespace());
41 protected HandlingPriority canHandle(final String operationName, final String operationNamespace) {
42 return operationName.equals(getOperationName()) && operationNamespace.equals(getOperationNamespace())
43 ? getHandlingPriority() : null;
46 public static final class OperationNameAndNamespace {
47 private final String operationName;
48 private final String namespace;
49 private final XmlElement operationElement;
51 public OperationNameAndNamespace(final Document message) throws DocumentedException {
52 final var requestElement = getRequestElementWithCheck(message);
53 operationElement = requestElement.getOnlyChildElement();
54 operationName = operationElement.getName();
55 namespace = operationElement.getNamespace();
58 public String getOperationName() {
62 public String getNamespace() {
66 public XmlElement getOperationElement() {
67 return operationElement;
71 protected static XmlElement getRequestElementWithCheck(final Document message) throws DocumentedException {
72 return XmlElement.fromDomElementWithExpected(message.getDocumentElement(), RpcMessage.ELEMENT_NAME,
76 protected @NonNull HandlingPriority getHandlingPriority() {
77 return HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY;
80 protected String getOperationNamespace() {
81 return NamespaceURN.BASE;
84 protected abstract String getOperationName();
87 public Document handle(final Document requestMessage,
88 final NetconfOperationChainedExecution subsequentOperation) throws DocumentedException {
89 final var requestElement = getRequestElementWithCheck(requestMessage);
90 final var document = XmlUtil.newDocument();
91 final var operationElement = requestElement.getOnlyChildElement();
92 final var attributes = requestElement.getAttributes();
94 final var response = handle(document, operationElement, subsequentOperation);
95 final var rpcReply = document.createElementNS(NamespaceURN.BASE, RpcReplyMessage.ELEMENT_NAME);
96 if (XmlUtil.hasNamespace(response)) {
97 rpcReply.appendChild(response);
99 // FIXME: use getLocalName() instead
100 final var responseNS = document.createElementNS(NamespaceURN.BASE, response.getNodeName());
101 final var list = response.getChildNodes();
102 while (list.getLength() != 0) {
103 responseNS.appendChild(list.item(0));
105 rpcReply.appendChild(responseNS);
108 for (var attribute : attributes.values()) {
109 rpcReply.setAttributeNode((Attr) document.importNode(attribute, true));
111 document.appendChild(rpcReply);
115 protected abstract Element handle(Document document, XmlElement message,
116 NetconfOperationChainedExecution subsequentOperation)
117 throws DocumentedException;
120 public String toString() {
121 final var sb = new StringBuilder(getClass().getName());
123 sb.append("{name=").append(getOperationName());
124 } catch (UnsupportedOperationException e) {
128 .append(", namespace=").append(getOperationNamespace())
129 .append(", session=").append(sessionId.getValue())