--- /dev/null
+/*
+ * Copyright (c) 2021 PANTHEON.tech, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.common;
+
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.collect.Maps;
+import java.util.Arrays;
+import java.util.Map;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+
+/**
+ * Enumeration of {@code error-severity} values, as defined by
+ * <a href="https://datatracker.ietf.org/doc/html/rfc4741#section-4.3">RFC4741, section 4.3</a>.
+ */
+@NonNullByDefault
+public enum ErrorSeverity {
+ /**
+ * An error preventing an operation from completing successfully.
+ */
+ ERROR("error", RpcError.ErrorSeverity.ERROR),
+ /**
+ * A warning not affecting an operation's ability to complete successfully.
+ */
+ WARNING("warning", RpcError.ErrorSeverity.ERROR);
+
+ private static final Map<String, ErrorSeverity> BY_ELEMENT_BODY =
+ Maps.uniqueIndex(Arrays.asList(values()), ErrorSeverity::elementBody);
+
+ private final RpcError.ErrorSeverity legacy;
+ private final String elementBody;
+
+ ErrorSeverity(final String elementName, final RpcError.ErrorSeverity legacy) {
+ this.elementBody = requireNonNull(elementName);
+ this.legacy = requireNonNull(legacy);
+ }
+
+ /**
+ * Return the XML element body of this object.
+ *
+ * @return element body of this object
+ */
+ public String elementBody() {
+ return elementBody;
+ }
+
+ @Deprecated
+ public RpcError.ErrorSeverity toLegacy() {
+ return legacy;
+ }
+
+ public static @Nullable ErrorSeverity forElementBody(final String elementBody) {
+ return BY_ELEMENT_BODY.get(requireNonNull(elementBody));
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2021 PANTHEON.tech, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.common;
+
+import static java.util.Objects.requireNonNull;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+
+/**
+ * Extensible enumeration of {@code error-tag} values, as defined in
+ * <a href="https://datatracker.ietf.org/doc/html/rfc6241#appendix-A">RFC6241</a>. These values are an extensible
+ * enumeration, since YANG does not place restriction on possible values in
+ * <a href="https://datatracker.ietf.org/doc/html/rfc8040#section-3.9">RFC8040</a>.
+ *
+ * <p>
+ * Error tag defines overall error semantics. Additional tag-specific information may be associated with a particular
+ * error tag.
+ */
+@NonNullByDefault
+public final class ErrorTag {
+ /**
+ * {@code access-denied} {@link ErrorTag}.
+ */
+ public static final ErrorTag ACCESS_DENIED = new ErrorTag("access-denied");
+ /**
+ * {@code bad-attribute} {@link ErrorTag}. Covers mechanics specified in RFC6020 section 8.3.1, bullet 6
+ * <pre>
+ * For insert handling, if the value for the attributes "before" and
+ * "after" are not valid for the type of the appropriate key leafs,
+ * the server MUST reply with a "bad-attribute" error-tag in the rpc-
+ * error.
+ * </pre>
+ */
+ public static final ErrorTag BAD_ATTRIBUTE = new ErrorTag("bad-attribute");
+ /**
+ * {@code bad-element} {@link ErrorTag}. Covers mechanics specified in RFC6020 section 8.3.1, bullet 3
+ * <pre>
+ * If data for more than one case branch of a choice is present, the
+ * server MUST reply with a "bad-element" in the rpc-error.
+ * </pre>
+ */
+ public static final ErrorTag BAD_ELEMENT = new ErrorTag("bad-element");
+ /**
+ * {@code data-exists} {@link ErrorTag}.
+ */
+ public static final ErrorTag DATA_EXISTS = new ErrorTag("data-exists");
+ /**
+ * {@code data-missing} {@link ErrorTag}. Covers mechanics specified in RFC6020 sections 13.5 through 13.7.
+ */
+ public static final ErrorTag DATA_MISSING = new ErrorTag("data-missing");
+ /**
+ * {@code in-use} {@link ErrorTag}.
+ */
+ public static final ErrorTag IN_USE = new ErrorTag("in-use");
+ /**
+ * {@code invalid-value} {@link ErrorTag}. Covers mechanics specified in RFC6020 section 8.3.1, bullet 1
+ * <pre>
+ * If a leaf data value does not match the type constraints for the
+ * leaf, including those defined in the type's "range", "length", and
+ * "pattern" properties, the server MUST reply with an
+ * "invalid-value" error-tag in the rpc-error, and with the error-
+ * app-tag and error-message associated with the constraint, if any
+ * exist.
+ * </pre>
+ */
+ public static final ErrorTag INVALID_VALUE = new ErrorTag("invalid-value");
+ /**
+ * {@code lock-denied} {@link ErrorTag}.
+ */
+ public static final ErrorTag LOCK_DENIED = new ErrorTag("lock-denied");
+ /**
+ * {@code missing-attribute} {@link ErrorTag}.
+ */
+ public static final ErrorTag MISSING_ATTRIBUTE = new ErrorTag("missing-attribute");
+ /**
+ * {@code missing-element} {@link ErrorTag}. Covers mechanics specified in RFC6020 section 8.3.1, bullet 2
+ * <pre>
+ * If all keys of a list entry are not present, the server MUST reply
+ * with a "missing-element" error-tag in the rpc-error.
+ * </pre>
+ * as well as RFC6020 section 7.13.2, paragraph 2
+ * <pre>
+ * If a leaf in the input tree has a "mandatory" statement with the
+ * value "true", the leaf MUST be present in a NETCONF RPC invocation.
+ * Otherwise, the server MUST return a "missing-element" error.
+ * </pre>
+ */
+ public static final ErrorTag MISSING_ELEMENT = new ErrorTag("missing-element");
+ /**
+ * {@code operation-failed} {@link ErrorTag}. Covers mechanics specified in RFC6020 section 13.1 through 13.4.
+ */
+ public static final ErrorTag OPERATION_FAILED = new ErrorTag("operation-failed");
+ /**
+ * {@code operation-not-supported} {@link ErrorTag}.
+ */
+ public static final ErrorTag OPERATION_NOT_SUPPORTED = new ErrorTag("operation-not-supported");
+ /**
+ * {@code partial-operation} {@link ErrorTag}.
+ * @deprecated This error-info is obsolete since RFC6241.
+ */
+ @Deprecated(since = "RFC6241")
+ public static final ErrorTag PARTIAL_OPERATION = new ErrorTag("partial-operation");
+ /**
+ * {@code resource-denied} {@link ErrorTag}.
+ */
+ public static final ErrorTag RESOURCE_DENIED = new ErrorTag("resource-denied");
+ /**
+ * {@code rollback-failed} {@link ErrorTag}.
+ */
+ public static final ErrorTag ROLLBACK_FAILED = new ErrorTag("rollback-failed");
+ /**
+ * {@code too-big} {@link ErrorTag}.
+ */
+ public static final ErrorTag TOO_BIG = new ErrorTag("too-big");
+ /**
+ * {@code unknown-element} {@link ErrorTag}. Covers mechanics specified in RFC6020 section 8.3.1, bullet 7
+ * <pre>
+ * If the attributes "before" and "after" appears in any element that
+ * is not a list whose "ordered-by" property is "user", the server
+ * MUST reply with an "unknown-attribute" error-tag in the rpc-error.
+ * </pre>
+ */
+ public static final ErrorTag UNKNOWN_ATTRIBUTE = new ErrorTag("unknown-attribute");
+ /**
+ * {@code unknown-element} {@link ErrorTag}. Covers mechanics specified in RFC6020 section 8.3.1, bullet 4
+ * <pre>
+ * If data for a node tagged with "if-feature" is present, and the
+ * feature is not supported by the device, the server MUST reply with
+ * an "unknown-element" error-tag in the rpc-error.
+ * </pre>
+ * as well as RFC6020 section 8.3.1, bullet 5
+ * <pre>
+ * If data for a node tagged with "when" is present, and the "when"
+ * condition evaluates to "false", the server MUST reply with an
+ * "unknown-element" error-tag in the rpc-error.
+ * </pre>
+ */
+ public static final ErrorTag UNKNOWN_ELEMENT = new ErrorTag("unknown-element");
+ /**
+ * {@code unknown-namespace} {@link ErrorTag}.
+ */
+ public static final ErrorTag UNKNOWN_NAMESPACE = new ErrorTag("unknown-namespace");
+
+ private final String elementBody;
+
+ public ErrorTag(final String elementBody) {
+ this.elementBody = requireNonNull(elementBody);
+ }
+
+ /**
+ * Return the XML element body of this object.
+ *
+ * @return element body of this object
+ */
+ public String elementBody() {
+ return elementBody;
+ }
+
+ @Override
+ public int hashCode() {
+ return elementBody.hashCode();
+ }
+
+ @Override
+ public boolean equals(final @Nullable Object obj) {
+ return obj == this || obj instanceof ErrorTag && elementBody.equals(((ErrorTag) obj).elementBody);
+ }
+
+ @Override
+ public String toString() {
+ return elementBody;
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2021 PANTHEON.tech, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.common;
+
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.collect.Maps;
+import java.util.Arrays;
+import java.util.Map;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+
+/**
+ * Enumeration of {@code error-type} values. These provide glue between {@link NetconfLayer} and various sources of
+ * such errors. This enumeration is not extensible in YANG as it is modeled in
+ * <a href="https://datatracker.ietf.org/doc/html/rfc8040#section-3.9">RFC8040</a>.
+ */
+@NonNullByDefault
+public enum ErrorType {
+ /**
+ * A {@link NetconfLayer#TRANSPORT} layer error. This typically happens on transport endpoints, where a protocol
+ * plugin needs to report a NETCONF-equivalent condition.
+ */
+ TRANSPORT("transport", NetconfLayer.TRANSPORT, RpcError.ErrorType.TRANSPORT),
+ /**
+ * A {@link NetconfLayer#RPC} layer error. This typically happens on request routers, where a request may end up
+ * being resolved due to implementation-internal causes, such as timeouts and state loss.
+ */
+ RPC("rpc", NetconfLayer.RPC, RpcError.ErrorType.RPC),
+ /**
+ * A {@link NetconfLayer#OPERATIONS} layer error. These typically happen in a NETCONF protocol implementation.
+ */
+ PROTOCOL("protocol", NetconfLayer.OPERATIONS, RpcError.ErrorType.PROTOCOL),
+ /**
+ * A {@link NetconfLayer#CONTENT} layer error. These typically happen due to YANG data handling, such as
+ * type checking and structural consistency.
+ */
+ APPLICATION("application", NetconfLayer.CONTENT, RpcError.ErrorType.APPLICATION);
+
+ private static final Map<String, ErrorType> BY_ELEMENT_BODY =
+ Maps.uniqueIndex(Arrays.asList(values()), ErrorType::elementBody);
+
+ private final RpcError.ErrorType legacy;
+ private final String elementBody;
+ private final NetconfLayer layer;
+
+ ErrorType(final String elementName, final NetconfLayer layer, final RpcError.ErrorType legacy) {
+ this.elementBody = requireNonNull(elementName);
+ this.layer = requireNonNull(layer);
+ this.legacy = requireNonNull(legacy);
+ }
+
+ /**
+ * Return the XML element body of this object.
+ *
+ * @return element body of this object
+ */
+ public String elementBody() {
+ return elementBody;
+ }
+
+ /**
+ * Return the {@link NetconfLayer} corresponding to this error type.
+ *
+ * @return A NETCONF layer
+ */
+ public final NetconfLayer layer() {
+ return layer;
+ }
+
+ @Deprecated
+ public final RpcError.ErrorType toLegacy() {
+ return legacy;
+ }
+
+ public static @Nullable ErrorType forElementBody(final String elementBody) {
+ return BY_ELEMENT_BODY.get(requireNonNull(elementBody));
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2021 PANTHEON.tech, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.common;
+
+/**
+ * Enumeration of NETCONF layers, as established in
+ * <a href="https://datatracker.ietf.org/doc/html/rfc4741#section-1.1">NETCONF</a>. This enumeration exists because
+ * its semantics are implied by RFC6020 references to {@code error-tag} and its XML encoding.
+ *
+ * <p>
+ * This enumeration corresponds to the {@code Layer} in:
+ * <pre><code>
+ * NETCONF can be conceptually partitioned into four layers:
+ *
+ * Layer Example
+ * +-------------+ +-----------------------------+
+ * (4) | Content | | Configuration data |
+ * +-------------+ +-----------------------------+
+ * | |
+ * +-------------+ +-----------------------------+
+ * (3) | Operations | | <get-config>, <edit-config> |
+ * +-------------+ +-----------------------------+
+ * | |
+ * +-------------+ +-----------------------------+
+ * (2) | RPC | | <rpc>, <rpc-reply> |
+ * +-------------+ +-----------------------------+
+ * | |
+ * +-------------+ +-----------------------------+
+ * (1) | Transport | | BEEP, SSH, SSL, console |
+ * | Protocol | | |
+ * +-------------+ +-----------------------------+
+ * </code></pre>
+ * as acknowledged in <a href="https://datatracker.ietf.org/doc/html/rfc6241#section-1.2">RFC6241</a>:
+ * <pre>
+ * The YANG data modeling language [RFC6020] has been developed for
+ * specifying NETCONF data models and protocol operations, covering the
+ * Operations and the Content layers of Figure 1.
+ * </pre>
+ */
+public enum NetconfLayer {
+ /**
+ * Content layer, for example configuration data. This layer is implied indirectly in constructs defined in
+ * {@link YangError} and corresponds to {@link ErrorType#APPLICATION}
+ */
+ CONTENT,
+ /**
+ * Operations layer, for example {@code <get-config>}, {@code <edit-config>} configuration data. This corresponds to
+ * {@link ErrorType#PROTOCOL}.
+ */
+ OPERATIONS,
+ /**
+ * RPC layer, for example {@code <rpc>}, {@code <rpc-reply>}. This corresponds to {@link ErrorType#RPC}.
+ */
+ RPC,
+ /**
+ * Transport protocol layer, for example BEEP, SSH, TLS, console. This corresponds to {@link ErrorType#TRANSPORT}.
+ */
+ TRANSPORT;
+}
*/
package org.opendaylight.yangtools.yang.common;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
/**
* Representation of an error.
- *
*/
public interface RpcError {
-
+ // FIXME: 8.0.0: remove this in favor of Netconf.ErrorSeverity
+ @NonNullByDefault
enum ErrorSeverity {
- ERROR,
- WARNING
+ ERROR {
+ @Override
+ public org.opendaylight.yangtools.yang.common.ErrorSeverity toNetconf() {
+ return org.opendaylight.yangtools.yang.common.ErrorSeverity.ERROR;
+ }
+ },
+ WARNING {
+ @Override
+ public org.opendaylight.yangtools.yang.common.ErrorSeverity toNetconf() {
+ return org.opendaylight.yangtools.yang.common.ErrorSeverity.WARNING;
+ }
+ };
+
+ public abstract org.opendaylight.yangtools.yang.common.ErrorSeverity toNetconf();
}
+ /**
+ * Enumeration of {@code error-type} values. These provide glue between {@link NetconfLayer} and various sources of
+ * such errors.
+ */
+ // FIXME: 8.0.0: remove this in favor of common.ErrorType
+ @NonNullByDefault
enum ErrorType {
/**
* Indicates an error occurred during transport of data, eg over the network.
*/
- TRANSPORT,
-
+ TRANSPORT {
+ @Override
+ public org.opendaylight.yangtools.yang.common.ErrorType toNetconf() {
+ return org.opendaylight.yangtools.yang.common.ErrorType.TRANSPORT;
+ }
+ },
/**
* Indicates an error occurred during a remote procedure call.
*/
- RPC,
-
+ RPC {
+ @Override
+ public org.opendaylight.yangtools.yang.common.ErrorType toNetconf() {
+ return org.opendaylight.yangtools.yang.common.ErrorType.RPC;
+ }
+ },
/**
* Indicates an error at a protocol layer, eg if invalid data was passed by the caller.
*/
- PROTOCOL,
-
+ PROTOCOL {
+ @Override
+ public org.opendaylight.yangtools.yang.common.ErrorType toNetconf() {
+ return org.opendaylight.yangtools.yang.common.ErrorType.PROTOCOL;
+ }
+ },
/**
* Indicates an error occurred during internal processing.
*/
- APPLICATION
+ APPLICATION {
+ @Override
+ public org.opendaylight.yangtools.yang.common.ErrorType toNetconf() {
+ return org.opendaylight.yangtools.yang.common.ErrorType.APPLICATION;
+ }
+ };
+
+ public abstract org.opendaylight.yangtools.yang.common.ErrorType toNetconf();
}
/**
* Returns a short string that identifies the general type of error condition.
*
* <p>
- * The following outlines suggested values as defined by netconf (<a href="https://tools.ietf.org/html/rfc6241#page-89">RFC 6241</a>):
+ * The following outlines suggested values as defined by
+ * (<a href="https://tools.ietf.org/html/rfc6241#page-89">RFC6241</a>):
+ *
* <pre>
* access-denied
* bad-attribute
* </pre>
* @return a string if available or null otherwise.
*/
+ // FIXME: 8.0.0: return ErrorTag here
String getTag();
/**
*
* @return a string if available or null otherwise.
*/
+ // FIXME: YANGTOOLS-765: this is wrong and needs to be modeled at data-api layer with YangErrorInfo
String getInfo();
/**
*/
public static final String YANG_XPATH_FUNCTIONS_PREFIX = "yang";
+ /**
+ * NETCONF protocol elements' namespace, as defined in
+ * <a href="https://datatracker.ietf.org/doc/html/rfc4741#section-3.1">RFC4741 section 3.1</a>, in String format.
+ */
+ public static final String NETCONF_NAMESPACE_STRING = "urn:ietf:params:xml:ns:netconf:base:1.0";
+
+ /**
+ * NETCONF protocol elements' namespace, as defined in
+ * <a href="https://datatracker.ietf.org/doc/html/rfc4741#section-3.1">RFC4741 section 3.1</a>, in String format.
+ */
+ public static final XMLNamespace NETCONF_NAMESPACE = XMLNamespace.of(NETCONF_NAMESPACE_STRING).intern();
+
+ /**
+ * NETCONF namespace bound to YANG through
+ * <a href="https://datatracker.ietf.org/doc/html/rfc6241#section-10.3">ietf-netconf@2011-06-01.yang</a>.
+ */
+ public static final QNameModule RFC6241_YANG_MODULE =
+ QNameModule.create(NETCONF_NAMESPACE, Revision.of("2011-06-01")).intern();
+
+ /**
+ * {@code bad-attribute}, value is the name of the attribute.
+ */
+ public static final QName BAD_ATTRIBUTE_QNAME = QName.create(RFC6241_YANG_MODULE, "bad-attribute").intern();
+ /**
+ * {@code bad-element}, value is the name of the element.
+ */
+ public static final QName BAD_ELEMENT_QNAME = QName.create(RFC6241_YANG_MODULE, "bad-element").intern();
+ /**
+ * {@code bad-namespace}, value is the name of the namespace.
+ */
+ public static final QName BAD_NAMESPACE_QNAME = QName.create(RFC6241_YANG_MODULE, "bad-namespace").intern();
+ /**
+ * {@code session-id}, value the session identifier, as modeled in {@code SessionIdOrZero}.
+ */
+ public static final QName SESSION_ID_QNAME = QName.create(RFC6241_YANG_MODULE, "session-id").intern();
+ @Deprecated(since = "RFC6241")
+ public static final QName ERR_ELEMENT_QNAME = QName.create(RFC6241_YANG_MODULE, "err-element").intern();
+ @Deprecated(since = "RFC6241")
+ public static final QName NOOP_ELEMENT_QNAME = QName.create(RFC6241_YANG_MODULE, "noop-element").intern();
+ @Deprecated(since = "RFC6241")
+ public static final QName OK_ELEMENT_QNAME = QName.create(RFC6241_YANG_MODULE, "ok-element").intern();
+ /**
+ * {@code missing-choice} as defined in
+ * <a href="https://datatracker.ietf.org/doc/html/rfc6020#section-13.7">RFC6020, section 13.7</a>.
+ */
+ public static final QName MISSING_CHOICE_QNAME = QName.create(RFC6020_YANG_MODULE, "missing-choice").intern();
+ /**
+ * {@code non-unique} as defined in
+ * <a href="https://datatracker.ietf.org/doc/html/rfc6020#section-13.1">RFC6020, section 13.1</a>.
+ */
+ public static final QName NON_UNIQUE_QNAME = QName.create(RFC6020_YANG_MODULE, "non-unique").intern();
+
// Dummy template UnqualifiedQName. These are never leaked, but are used for efficient instantiation via
// UnqualifiedQName#bindTo()
private static final UnqualifiedQName DUMMY_OPERATION_INPUT = UnqualifiedQName.of("input");
import org.opendaylight.yangtools.yang.common.QNameModule;
import org.opendaylight.yangtools.yang.common.Revision;
import org.opendaylight.yangtools.yang.common.XMLNamespace;
+import org.opendaylight.yangtools.yang.common.YangConstants;
import org.opendaylight.yangtools.yang.xpath.api.YangXPathExpression.QualifiedBound;
/**
* QName of NETCONF top-level data node.
*/
// FIXME: YANGTOOLS-1074: we do not want this name
- @NonNull QName NAME = QName.create(XMLNamespace.of("urn:ietf:params:xml:ns:netconf:base:1.0"), "data").intern();
+ @NonNull QName NAME = QName.create(YangConstants.NETCONF_NAMESPACE, "data").intern();
/**
* Returns data schema node instances which represents direct subnodes (like