import org.opendaylight.mdsal.dom.api.DOMDataBroker;
import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
import org.opendaylight.netconf.api.DocumentedException;
-import org.opendaylight.netconf.api.DocumentedException.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.opendaylight.netconf.api.xml.XmlUtil;
import org.opendaylight.netconf.util.mapping.AbstractSingletonNetconfOperation;
import org.opendaylight.yangtools.yang.common.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
final Optional<XmlElement> urlElement = parent.getOnlyChildElementOptionally(URL_KEY);
if (urlElement.isEmpty()) {
throw new DocumentedException("Invalid RPC, neither <config> not <url> element is present",
- ErrorType.PROTOCOL, DocumentedException.ErrorTag.MISSING_ELEMENT, ErrorSeverity.ERROR);
+ ErrorType.PROTOCOL, ErrorTag.MISSING_ELEMENT, ErrorSeverity.ERROR);
}
final Document document = getDocumentFromUrl(urlElement.get().getTextContent());
return XmlUtil.readXmlToDocument(input);
} catch (MalformedURLException e) {
throw new DocumentedException(url + " URL is invalid or unsupported", e,
- ErrorType.APPLICATION, DocumentedException.ErrorTag.INVALID_VALUE, ErrorSeverity.ERROR);
+ ErrorType.APPLICATION, ErrorTag.INVALID_VALUE, ErrorSeverity.ERROR);
} catch (IOException e) {
throw new DocumentedException("Could not open URL " + url, e,
- ErrorType.APPLICATION, DocumentedException.ErrorTag.OPERATION_FAILED, ErrorSeverity.ERROR);
+ ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED, ErrorSeverity.ERROR);
} catch (SAXException e) {
throw new DocumentedException("Could not parse XML at" + url, e,
- ErrorType.APPLICATION, DocumentedException.ErrorTag.OPERATION_FAILED, ErrorSeverity.ERROR);
+ ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED, ErrorSeverity.ERROR);
}
}
import javax.xml.stream.XMLStreamException;
import javax.xml.transform.dom.DOMSource;
import org.opendaylight.netconf.api.DocumentedException;
-import org.opendaylight.netconf.api.DocumentedException.ErrorTag;
import org.opendaylight.netconf.api.NetconfDocumentedException;
import org.opendaylight.netconf.api.xml.XmlElement;
import org.opendaylight.netconf.mdsal.connector.CurrentSchemaContext;
import org.opendaylight.yangtools.yang.common.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.XMLNamespace;
xmlParser.traverse(new DOMSource(element.getDomElement()));
} catch (final XMLStreamException | URISyntaxException | IOException | SAXException ex) {
throw new NetconfDocumentedException("Error parsing input: " + ex.getMessage(), ex, ErrorType.PROTOCOL,
- ErrorTag.MALFORMED_MESSAGE, ErrorSeverity.ERROR);
+ DocumentedException.MALFORMED_MESSAGE, ErrorSeverity.ERROR);
}
}
import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
import org.opendaylight.netconf.api.DocumentedException;
-import org.opendaylight.netconf.api.DocumentedException.ErrorTag;
import org.opendaylight.netconf.api.xml.XmlElement;
import org.opendaylight.netconf.api.xml.XmlNetconfConstants;
import org.opendaylight.netconf.api.xml.XmlUtil;
import org.opendaylight.netconf.mdsal.connector.CurrentSchemaContext;
import org.opendaylight.netconf.mdsal.connector.TransactionProvider;
import org.opendaylight.yangtools.yang.common.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
final Optional<XmlElement> sourceElement = parent.getOnlyChildElementOptionally(SOURCE_KEY);
if (sourceElement.isEmpty()) {
throw new DocumentedException("<source> element is missing",
- ErrorType.PROTOCOL, DocumentedException.ErrorTag.MISSING_ELEMENT, ErrorSeverity.ERROR);
+ ErrorType.PROTOCOL, ErrorTag.MISSING_ELEMENT, ErrorSeverity.ERROR);
}
return sourceElement.get();
import java.util.HashMap;
import java.util.Map;
import org.opendaylight.netconf.api.DocumentedException;
-import org.opendaylight.netconf.api.DocumentedException.ErrorTag;
import org.opendaylight.netconf.api.xml.XmlElement;
import org.opendaylight.netconf.api.xml.XmlNetconfConstants;
import org.opendaylight.netconf.mdsal.connector.TransactionProvider;
import org.opendaylight.netconf.util.mapping.AbstractSingletonNetconfOperation;
import org.opendaylight.yangtools.yang.common.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
} catch (final IllegalStateException e) {
LOG.warn("Abort failed ", e);
final Map<String, String> errorInfo = new HashMap<>();
- errorInfo.put(ErrorTag.OPERATION_FAILED.name(),
+ errorInfo.put(ErrorTag.OPERATION_FAILED.elementBody(),
"Operation failed. Use 'get-config' or 'edit-config' before triggering "
+ OPERATION_NAME + " operation");
throw new DocumentedException(e.getMessage(), e, ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED,
import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
import org.opendaylight.netconf.api.DocumentedException;
-import org.opendaylight.netconf.api.DocumentedException.ErrorTag;
import org.opendaylight.netconf.api.ModifyAction;
import org.opendaylight.netconf.api.xml.XmlElement;
import org.opendaylight.netconf.api.xml.XmlNetconfConstants;
import org.opendaylight.netconf.mdsal.connector.CurrentSchemaContext;
import org.opendaylight.netconf.mdsal.connector.TransactionProvider;
import org.opendaylight.yangtools.yang.common.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
import org.opendaylight.netconf.api.xml.XmlNetconfConstants;
import org.opendaylight.netconf.util.mapping.AbstractSingletonNetconfOperation;
import org.opendaylight.yangtools.yang.common.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
}
throw new DocumentedException("Unable to lock " + targetDatastore + " datastore",
- ErrorType.APPLICATION, DocumentedException.ErrorTag.OPERATION_NOT_SUPPORTED, ErrorSeverity.ERROR);
+ ErrorType.APPLICATION, ErrorTag.OPERATION_NOT_SUPPORTED, ErrorSeverity.ERROR);
}
static Datastore extractTargetParameter(final XmlElement operationElement) throws DocumentedException {
import org.opendaylight.mdsal.dom.api.DOMRpcResult;
import org.opendaylight.mdsal.dom.api.DOMRpcService;
import org.opendaylight.netconf.api.DocumentedException;
-import org.opendaylight.netconf.api.DocumentedException.ErrorTag;
import org.opendaylight.netconf.api.NetconfDocumentedException;
import org.opendaylight.netconf.api.xml.XmlElement;
import org.opendaylight.netconf.api.xml.XmlNetconfConstants;
import org.opendaylight.netconf.mdsal.connector.CurrentSchemaContext;
import org.opendaylight.netconf.util.mapping.AbstractSingletonNetconfOperation;
import org.opendaylight.yangtools.yang.common.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.opendaylight.yangtools.yang.common.XMLNamespace;
import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
xmlParser.traverse(new DOMSource(element.getDomElement()));
} catch (final XMLStreamException | URISyntaxException | IOException | SAXException ex) {
throw new NetconfDocumentedException("Error parsing input: " + ex.getMessage(), ex, ErrorType.PROTOCOL,
- ErrorTag.MALFORMED_MESSAGE, ErrorSeverity.ERROR);
+ DocumentedException.MALFORMED_MESSAGE, ErrorSeverity.ERROR);
}
return (ContainerNode) resultHolder.getResult();
import org.opendaylight.netconf.api.xml.XmlNetconfConstants;
import org.opendaylight.netconf.util.mapping.AbstractSingletonNetconfOperation;
import org.opendaylight.yangtools.yang.common.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
}
throw new DocumentedException("Unable to unlock " + targetDatastore + " datastore",
- ErrorType.APPLICATION, DocumentedException.ErrorTag.OPERATION_NOT_SUPPORTED, ErrorSeverity.ERROR);
+ ErrorType.APPLICATION, ErrorTag.OPERATION_NOT_SUPPORTED, ErrorSeverity.ERROR);
}
@Override
import com.google.common.collect.ImmutableMap;
import org.opendaylight.netconf.api.DocumentedException;
-import org.opendaylight.netconf.api.DocumentedException.ErrorTag;
import org.opendaylight.netconf.api.xml.XmlElement;
import org.opendaylight.netconf.api.xml.XmlNetconfConstants;
import org.opendaylight.netconf.mdsal.connector.TransactionProvider;
import org.opendaylight.yangtools.yang.common.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.xml.stream.XMLStreamWriter;
import javax.xml.transform.dom.DOMResult;
import org.opendaylight.netconf.api.DocumentedException;
-import org.opendaylight.netconf.api.DocumentedException.ErrorTag;
import org.opendaylight.netconf.api.xml.XmlElement;
import org.opendaylight.netconf.api.xml.XmlNetconfConstants;
import org.opendaylight.netconf.mdsal.connector.CurrentSchemaContext;
import org.opendaylight.netconf.mdsal.connector.ops.Datastore;
import org.opendaylight.netconf.util.mapping.AbstractSingletonNetconfOperation;
import org.opendaylight.yangtools.yang.common.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
import org.opendaylight.netconf.api.xml.XmlElement;
import org.opendaylight.netconf.mdsal.connector.CurrentSchemaContext;
import org.opendaylight.yangtools.yang.common.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.XMLNamespace;
} catch (final ValidationException e) {
LOG.debug("Filter content isn't valid", e);
throw new DocumentedException("Validation failed. Cause: " + e.getMessage(), e,
- ErrorType.APPLICATION, DocumentedException.ErrorTag.UNKNOWN_NAMESPACE, ErrorSeverity.ERROR);
+ ErrorType.APPLICATION, ErrorTag.UNKNOWN_NAMESPACE, ErrorSeverity.ERROR);
}
}
}
throw new DocumentedException("Unable to find node with namespace: " + nameSpace + " in schema context: "
+ schemaContext.getCurrentContext(),
- ErrorType.APPLICATION, DocumentedException.ErrorTag.UNKNOWN_NAMESPACE, ErrorSeverity.ERROR);
+ ErrorType.APPLICATION, ErrorTag.UNKNOWN_NAMESPACE, ErrorSeverity.ERROR);
}
/**
import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
import org.opendaylight.netconf.api.DocumentedException;
-import org.opendaylight.netconf.api.DocumentedException.ErrorTag;
import org.opendaylight.netconf.api.xml.XmlElement;
import org.opendaylight.netconf.api.xml.XmlNetconfConstants;
import org.opendaylight.netconf.mdsal.connector.CurrentSchemaContext;
import org.opendaylight.netconf.mdsal.connector.TransactionProvider;
import org.opendaylight.netconf.mdsal.connector.ops.Datastore;
import org.opendaylight.yangtools.yang.common.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
import org.opendaylight.netconf.api.DocumentedException;
-import org.opendaylight.netconf.api.DocumentedException.ErrorTag;
import org.opendaylight.netconf.api.xml.XmlElement;
import org.opendaylight.netconf.api.xml.XmlNetconfConstants;
import org.opendaylight.netconf.mdsal.connector.CurrentSchemaContext;
import org.opendaylight.netconf.mdsal.connector.TransactionProvider;
import org.opendaylight.netconf.mdsal.connector.ops.Datastore;
import org.opendaylight.yangtools.yang.common.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.opendaylight.netconf.api.DocumentedException;
-import org.opendaylight.netconf.api.DocumentedException.ErrorTag;
import org.opendaylight.netconf.api.xml.XmlUtil;
import org.opendaylight.netconf.util.test.XmlFileLoader;
import org.opendaylight.yangtools.yang.common.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
import java.net.URI;
import org.junit.Test;
import org.opendaylight.netconf.api.DocumentedException;
-import org.opendaylight.netconf.api.DocumentedException.ErrorTag;
import org.opendaylight.netconf.api.xml.XmlElement;
import org.opendaylight.netconf.api.xml.XmlUtil;
import org.opendaylight.netconf.mdsal.connector.CurrentSchemaContext;
import org.opendaylight.netconf.mdsal.connector.ops.get.GetConfig;
import org.opendaylight.netconf.util.test.XmlFileLoader;
import org.opendaylight.yangtools.yang.common.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.mdsal.dom.api.DOMSchemaService;
import org.opendaylight.mdsal.dom.spi.DefaultDOMRpcResult;
import org.opendaylight.netconf.api.DocumentedException;
-import org.opendaylight.netconf.api.DocumentedException.ErrorTag;
import org.opendaylight.netconf.api.xml.XmlUtil;
import org.opendaylight.netconf.mapping.api.HandlingPriority;
import org.opendaylight.netconf.mapping.api.NetconfOperationChainedExecution;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.concepts.NoOpListenerRegistration;
import org.opendaylight.yangtools.yang.common.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.XMLNamespace;
import org.opendaylight.netconf.mdsal.connector.TransactionProvider;
import org.opendaylight.yangtools.util.concurrent.FluentFutures;
import org.opendaylight.yangtools.yang.common.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.w3c.dom.Document;
final DocumentedException e = assertThrows(DocumentedException.class,
() -> validate("messages/mapping/validate/validate.xml"));
assertEquals(ErrorSeverity.ERROR, e.getErrorSeverity());
- assertEquals(DocumentedException.ErrorTag.OPERATION_NOT_SUPPORTED, e.getErrorTag());
+ assertEquals(ErrorTag.OPERATION_NOT_SUPPORTED, e.getErrorTag());
assertEquals(ErrorType.PROTOCOL, e.getErrorType());
}
final DocumentedException e = assertThrows(DocumentedException.class,
() -> validate("messages/mapping/validate/validate_no_source.xml"));
assertEquals(ErrorSeverity.ERROR, e.getErrorSeverity());
- assertEquals(DocumentedException.ErrorTag.MISSING_ELEMENT, e.getErrorTag());
+ assertEquals(ErrorTag.MISSING_ELEMENT, e.getErrorTag());
assertEquals(ErrorType.PROTOCOL, e.getErrorType());
}
final DocumentedException e = assertThrows(DocumentedException.class,
() -> validate("messages/mapping/validate/validate_running.xml"));
assertEquals(ErrorSeverity.ERROR, e.getErrorSeverity());
- assertEquals(DocumentedException.ErrorTag.OPERATION_NOT_SUPPORTED, e.getErrorTag());
+ assertEquals(ErrorTag.OPERATION_NOT_SUPPORTED, e.getErrorTag());
assertEquals(ErrorType.PROTOCOL, e.getErrorType());
}
final DocumentedException e = assertThrows(DocumentedException.class,
() -> validate("messages/mapping/validate/validate.xml", transactionProvider));
assertEquals(ErrorSeverity.ERROR, e.getErrorSeverity());
- assertEquals(DocumentedException.ErrorTag.OPERATION_FAILED, e.getErrorTag());
+ assertEquals(ErrorTag.OPERATION_FAILED, e.getErrorTag());
assertEquals(ErrorType.APPLICATION, e.getErrorType());
}
import org.opendaylight.netconf.api.xml.XmlUtil;
import org.opendaylight.netconf.util.mapping.AbstractSingletonNetconfOperation;
import org.opendaylight.yangtools.yang.common.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
schema = cap.getSchemaForCapability(entry.identifier, entry.version);
} catch (final IllegalStateException e) {
final Map<String, String> errorInfo = new HashMap<>();
- errorInfo.put(DocumentedException.ErrorTag.OPERATION_FAILED.toString(), e.getMessage());
- LOG.warn("Rpc error: {}", DocumentedException.ErrorTag.OPERATION_FAILED, e);
+ // FIXME: so we have an <operation-failed>e.getMessage()</operation-failed> ??? In which namespace? Why?
+ errorInfo.put(ErrorTag.OPERATION_FAILED.elementBody(), e.getMessage());
+ LOG.warn("Rpc error: {}", ErrorTag.OPERATION_FAILED, e);
throw new DocumentedException(e.getMessage(), e, ErrorType.APPLICATION,
- DocumentedException.ErrorTag.OPERATION_FAILED, ErrorSeverity.ERROR, errorInfo);
+ ErrorTag.OPERATION_FAILED, ErrorSeverity.ERROR, errorInfo);
}
final Element getSchemaResult;
import static org.opendaylight.netconf.api.xml.XmlNetconfConstants.RPC_REPLY_KEY;
import static org.opendaylight.netconf.api.xml.XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.opendaylight.yangtools.yang.common.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
* Checked exception to communicate an error that needs to be sent to the
* netconf client.
*/
+// FIXME: NETCONF-793: implement YangNetconfErrorAware
public class DocumentedException extends Exception {
public static final String RPC_ERROR = "rpc-error";
public static final String ERROR_MESSAGE = "error-message";
public static final String ERROR_INFO = "error-info";
- private static final long serialVersionUID = 1L;
+ // FIXME: This is an RFC6241 definition, remove it once we have yangtools-7.0.5
+ @Deprecated(forRemoval = true)
+ public static final ErrorTag MALFORMED_MESSAGE = new ErrorTag("malformed-message");
+ private static final long serialVersionUID = 1L;
private static final Logger LOG = LoggerFactory.getLogger(DocumentedException.class);
-
private static final DocumentBuilderFactory BUILDER_FACTORY;
static {
BUILDER_FACTORY.setIgnoringComments(true);
}
- public enum ErrorTag {
- ACCESS_DENIED("access-denied"),
- BAD_ATTRIBUTE("bad-attribute"),
- BAD_ELEMENT("bad-element"),
- DATA_EXISTS("data-exists"),
- DATA_MISSING("data-missing"),
- IN_USE("in-use"),
- INVALID_VALUE("invalid-value"),
- LOCK_DENIED("lock-denied"),
- MALFORMED_MESSAGE("malformed-message"),
- MISSING_ATTRIBUTE("missing-attribute"),
- MISSING_ELEMENT("missing-element"),
- OPERATION_FAILED("operation-failed"),
- OPERATION_NOT_SUPPORTED("operation-not-supported"),
- RESOURCE_DENIED("resource-denied"),
- ROLLBCK_FAILED("rollback-failed"),
- TOO_BIG("too-big"),
- UNKNOWN_ATTRIBUTE("unknown-attribute"),
- UNKNOWN_ELEMENT("unknown-element"),
- UNKNOWN_NAMESPACE("unknown-namespace");
-
- private final String tagValue;
-
- ErrorTag(final String tagValue) {
- this.tagValue = tagValue;
- }
-
- public String getTagValue() {
- return this.tagValue;
- }
-
- public static ErrorTag from(final String text) {
- for (ErrorTag e : values()) {
- if (e.getTagValue().equals(text)) {
- return e;
- }
- }
-
- return OPERATION_FAILED;
- }
- }
-
private final ErrorType errorType;
+ @SuppressFBWarnings(value = "SE_BAD_FIELD", justification = "FIXME: should not be necessary with yangtools-7.0.5")
private final ErrorTag errorTag;
private final ErrorSeverity errorSeverity;
private final Map<String, String> errorInfo;
this.errorType = errorType;
this.errorTag = errorTag;
this.errorSeverity = errorSeverity;
+ // FIXME: this contract (based on what fromXMLDocument does) is quite wrong. It ignores the XML realities of
+ // what constitutes a tag and especially tag value when faced with encoding XML-namespaced entities --
+ // such as 'identity' arguments -- represented as QNames.
this.errorInfo = errorInfo;
}
- public static <E extends Exception> DocumentedException wrap(final E exception) throws DocumentedException {
- final Map<String, String> errorInfo = new HashMap<>();
- errorInfo.put(ErrorTag.OPERATION_FAILED.name(), "Exception thrown");
+ public static DocumentedException wrap(final Exception exception) throws DocumentedException {
throw new DocumentedException(exception.getMessage(), exception, ErrorType.APPLICATION,
- ErrorTag.OPERATION_FAILED, ErrorSeverity.ERROR, errorInfo);
+ ErrorTag.OPERATION_FAILED, ErrorSeverity.ERROR,
+ Map.of(ErrorTag.OPERATION_FAILED.elementBody(), "Exception thrown"));
}
public static DocumentedException fromXMLDocument(final Document fromDoc) {
Node rpcReply = fromDoc.getDocumentElement();
- // FIXME: BUG? - we only handle one rpc-error. For now, shove extra errorMessages
- // found in multiple rpc-error in the errorInfo Map to at least let them propagate
- // back to caller.
+ // FIXME: we only handle one rpc-error. For now, shove extra errorMessages found in multiple rpc-error in the
+ // errorInfo Map to at least let them propagate back to caller.
+ // this will be solved through migration to YangNetconfErrorAware, as that allows reporting multipl
+ // error events
int rpcErrorCount = 0;
NodeList replyChildren = rpcReply.getChildNodes();
// FIXME: this should be a hard error
errorType = type != null ? type : ErrorType.APPLICATION;
} else if (ERROR_TAG.equals(rpcErrorChild.getLocalName())) {
- errorTag = ErrorTag.from(rpcErrorChild.getTextContent());
+ errorTag = new ErrorTag(rpcErrorChild.getTextContent());
} else if (ERROR_SEVERITY.equals(rpcErrorChild.getLocalName())) {
final ErrorSeverity sev = ErrorSeverity.forElementBody(rpcErrorChild.getTextContent());
// FIXME: this should be a hard error
for (int i = 0; i < children.getLength(); i++) {
Node child = children.item(i);
if (child.getNodeType() == Node.ELEMENT_NODE) {
+ // FIXME: Holy namespace ignorance, Batman!
+ //
+ // So this is just not enough to decode things in the general sense. getTextContenxt() may easily be a
+ // qualified QName, such as an identity name or an instance-identifier. What the entire 'infoMap' needs
+ // to contain is each child's XML context, so that the string literal can be interpreted as needed.
+ //
+ // yang.common.YangNamespaceContext represents the minimal API surface that needs to be exposed. That
+ // effectively means:
+ //
+ // final class ElementValue implements YangNamespaceContext {
+ // public final String elementContenxt();
+ // }
+ //
+ // Map<QName, ElementValue> infoMap;
+ //
+ // except... what do we use for revision?
infoMap.put(child.getNodeName(), child.getTextContent());
}
}
return infoMap;
}
+ // FIXME: NETCONF-793: remove all of these in favor of YangNetconfErrorAware
public ErrorType getErrorType() {
return this.errorType;
}
return this.errorInfo;
}
+ // FIXME: this really should be an spi/util method (or even netconf-util-w3c-dom?) as this certainly is not the
+ // primary interface we want to expose -- it is inherently mutable and its API is a pure nightmare.
public Document toXMLDocument() {
Document doc = null;
try {
rpcReply.appendChild(rpcError);
rpcError.appendChild(createTextNode(doc, ERROR_TYPE, getErrorType().elementBody()));
- rpcError.appendChild(createTextNode(doc, ERROR_TAG, getErrorTag().getTagValue()));
+ rpcError.appendChild(createTextNode(doc, ERROR_TAG, getErrorTag().elementBody()));
rpcError.appendChild(createTextNode(doc, ERROR_SEVERITY, getErrorSeverity().elementBody()));
rpcError.appendChild(createTextNode(doc, ERROR_MESSAGE, getLocalizedMessage()));
return doc;
}
- private Node createTextNode(final Document doc, final String tag, final String textContent) {
+ private static Node createTextNode(final Document doc, final String tag, final String textContent) {
Node node = doc.createElementNS(URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0, tag);
node.setTextContent(textContent);
return node;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.Map;
import org.opendaylight.yangtools.yang.common.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.w3c.dom.Document;
import java.util.Map;
import org.opendaylight.netconf.api.DocumentedException;
import org.opendaylight.yangtools.yang.common.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
public class MissingNameSpaceException extends DocumentedException {
import java.util.Map;
import org.opendaylight.netconf.api.DocumentedException;
import org.opendaylight.yangtools.yang.common.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
public class UnexpectedElementException extends DocumentedException {
import java.util.Map;
import org.opendaylight.netconf.api.DocumentedException;
import org.opendaylight.yangtools.yang.common.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
public class UnexpectedNamespaceException extends DocumentedException {
private static final long serialVersionUID = 1L;
+ public UnexpectedNamespaceException(final String format, final Object... args) {
+ this(String.format(format, args), ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED, ErrorSeverity.ERROR);
+ }
+
public UnexpectedNamespaceException(final String message, final ErrorType errorType, final ErrorTag errorTag,
final ErrorSeverity errorSeverity) {
this(message, errorType, errorTag, errorSeverity, Map.of());
import javax.xml.XMLConstants;
import org.opendaylight.netconf.api.DocumentedException;
import org.opendaylight.yangtools.yang.common.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
} else {
if (!attribKey.startsWith(XMLConstants.XMLNS_ATTRIBUTE + ":")) {
throw new DocumentedException("Attribute doesn't start with :",
- ErrorType.APPLICATION, DocumentedException.ErrorTag.INVALID_VALUE, ErrorSeverity.ERROR);
+ ErrorType.APPLICATION, ErrorTag.INVALID_VALUE, ErrorSeverity.ERROR);
}
prefix = attribKey.substring(XMLConstants.XMLNS_ATTRIBUTE.length() + 1);
}
public void checkName(final String expectedName) throws UnexpectedElementException {
if (!getName().equals(expectedName)) {
- throw new UnexpectedElementException(String.format("Expected %s xml element but was %s", expectedName,
- getName()),
- ErrorType.APPLICATION, DocumentedException.ErrorTag.OPERATION_FAILED, ErrorSeverity.ERROR);
+ throw new UnexpectedElementException(
+ String.format("Expected %s xml element but was %s", expectedName, getName()),
+ ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED, ErrorSeverity.ERROR);
}
}
if (!getNamespaceAttribute().equals(expectedNamespace)) {
throw new UnexpectedNamespaceException(
String.format("Unexpected namespace %s should be %s", getNamespaceAttribute(), expectedNamespace),
- ErrorType.APPLICATION, DocumentedException.ErrorTag.OPERATION_FAILED, ErrorSeverity.ERROR);
+ ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED, ErrorSeverity.ERROR);
}
}
if (!getNamespace().equals(expectedNamespace)) {
throw new UnexpectedNamespaceException(
String.format("Unexpected namespace %s should be %s", getNamespace(), expectedNamespace),
- ErrorType.APPLICATION, DocumentedException.ErrorTag.OPERATION_FAILED, ErrorSeverity.ERROR);
+ ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED, ErrorSeverity.ERROR);
}
}
if (children.size() != 1) {
throw new DocumentedException(String.format("One element %s:%s expected in %s but was %s", namespace,
childName, toString(), children.size()),
- ErrorType.APPLICATION, DocumentedException.ErrorTag.INVALID_VALUE, ErrorSeverity.ERROR);
+ ErrorType.APPLICATION, ErrorTag.INVALID_VALUE, ErrorSeverity.ERROR);
}
return children.get(0);
List<XmlElement> nameElements = getChildElements(childName);
if (nameElements.size() != 1) {
throw new DocumentedException("One element " + childName + " expected in " + toString(),
- ErrorType.APPLICATION, DocumentedException.ErrorTag.INVALID_VALUE, ErrorSeverity.ERROR);
+ ErrorType.APPLICATION, ErrorTag.INVALID_VALUE, ErrorSeverity.ERROR);
}
return nameElements.get(0);
}
public XmlElement getOnlyChildElement() throws DocumentedException {
List<XmlElement> children = getChildElements();
if (children.size() != 1) {
- throw new DocumentedException(String.format("One element expected in %s but was %s", toString(),
- children.size()),
- ErrorType.APPLICATION, DocumentedException.ErrorTag.INVALID_VALUE, ErrorSeverity.ERROR);
+ throw new DocumentedException(
+ String.format("One element expected in %s but was %s", toString(), children.size()),
+ ErrorType.APPLICATION, ErrorTag.INVALID_VALUE, ErrorSeverity.ERROR);
}
return children.get(0);
}
}
}
throw new DocumentedException(getName() + " should contain text.",
- ErrorType.APPLICATION, DocumentedException.ErrorTag.INVALID_VALUE, ErrorSeverity.ERROR);
+ ErrorType.APPLICATION, ErrorTag.INVALID_VALUE, ErrorSeverity.ERROR);
}
public Optional<String> getOnlyTextContentOptionally() {
String attribute = element.getAttribute(XMLConstants.XMLNS_ATTRIBUTE);
if (attribute.isEmpty() || attribute.equals(DEFAULT_NAMESPACE_PREFIX)) {
throw new MissingNameSpaceException(String.format("Element %s must specify namespace", toString()),
- ErrorType.APPLICATION, DocumentedException.ErrorTag.OPERATION_FAILED, ErrorSeverity.ERROR);
+ ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED, ErrorSeverity.ERROR);
}
return attribute;
}
Optional<String> namespaceURI = getNamespaceOptionally();
if (namespaceURI.isEmpty()) {
throw new MissingNameSpaceException(String.format("No namespace defined for %s", this),
- ErrorType.APPLICATION, DocumentedException.ErrorTag.OPERATION_FAILED, ErrorSeverity.ERROR);
+ ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED, ErrorSeverity.ERROR);
}
return namespaceURI.get();
}
}
if (!childElements.isEmpty()) {
throw new DocumentedException(String.format("Unrecognised elements %s in %s", childElements, this),
- ErrorType.APPLICATION, DocumentedException.ErrorTag.INVALID_VALUE, ErrorSeverity.ERROR);
+ ErrorType.APPLICATION, ErrorTag.INVALID_VALUE, ErrorSeverity.ERROR);
}
}
BUILDER_FACTORY = factory;
}
- private static final ThreadLocal<DocumentBuilder> DEFAULT_DOM_BUILDER = new ThreadLocal<DocumentBuilder>() {
+ private static final ThreadLocal<DocumentBuilder> DEFAULT_DOM_BUILDER = new ThreadLocal<>() {
@Override
protected DocumentBuilder initialValue() {
try {
import org.junit.Test;
import org.opendaylight.netconf.api.xml.XmlNetconfConstants;
import org.opendaylight.yangtools.yang.common.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
public void testToAndFromXMLDocument() throws XPathExpressionException {
final String errorMessage = "mock error message";
DocumentedException ex = new NetconfDocumentedException(errorMessage, null, ErrorType.PROTOCOL,
- DocumentedException.ErrorTag.DATA_EXISTS, ErrorSeverity.WARNING, Map.of("foo", "bar"));
+ ErrorTag.DATA_EXISTS, ErrorSeverity.WARNING, Map.of("foo", "bar"));
final Document doc = ex.toXMLDocument();
assertNotNull("Document is null", doc);
final Node errorTagNode = getNode("netconf:error-tag", rpcErrorNode);
assertNotNull("error-tag not found", errorTagNode);
- assertEquals("error-tag", DocumentedException.ErrorTag.DATA_EXISTS.getTagValue(),
- errorTagNode.getTextContent());
+ assertEquals("error-tag", ErrorTag.DATA_EXISTS.elementBody(), errorTagNode.getTextContent());
final Node errorSeverityNode = getNode("netconf:error-severity", rpcErrorNode);
assertNotNull("error-severity not found", errorSeverityNode);
assertNotNull("NetconfDocumentedException is null", ex);
assertEquals("getErrorSeverity", ErrorSeverity.WARNING, ex.getErrorSeverity());
- assertEquals("getErrorTag", DocumentedException.ErrorTag.DATA_EXISTS, ex.getErrorTag());
+ assertEquals("getErrorTag", ErrorTag.DATA_EXISTS, ex.getErrorTag());
assertEquals("getErrorType", ErrorType.PROTOCOL, ex.getErrorType());
assertEquals("getLocalizedMessage", errorMessage, ex.getLocalizedMessage());
assertEquals("getErrorInfo", Map.of("foo", "bar"), ex.getErrorInfo());
final DocumentedException e = assertThrows(DocumentedException.class,
() -> xmlElement.checkUnrecognisedElements(xmlElement.getOnlyChildElement("inner")));
- assertThat(e.getMessage(), both(containsString("innerNamespace")).and(containsString("innerNamespace")));
+ assertThat(e.getMessage(),
+ // FIXME: this looks very suspect
+ both(containsString("innerNamespace")).and(containsString("innerNamespace")));
}
}
import org.opendaylight.netconf.util.messages.SendErrorExceptionUtil;
import org.opendaylight.netconf.util.messages.SubtreeFilter;
import org.opendaylight.yangtools.yang.common.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
* unexpected element Description: An unexpected element is present.
*/
throw new DocumentedException("Unknown tag " + rootNode.getNodeName() + " in message:\n" + netconfMessage,
- ErrorType.PROTOCOL, DocumentedException.ErrorTag.UNKNOWN_ELEMENT, ErrorSeverity.ERROR,
+ ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT, ErrorSeverity.ERROR,
ImmutableMap.of("bad-element", rootNode.getNodeName()));
}
}
}
throw new DocumentedException("Missing attribute " + rootNode.getNodeName(),
- ErrorType.RPC, DocumentedException.ErrorTag.MISSING_ATTRIBUTE, ErrorSeverity.ERROR, ImmutableMap.of(
+ ErrorType.RPC, ErrorTag.MISSING_ATTRIBUTE, ErrorSeverity.ERROR, ImmutableMap.of(
"bad-attribute", XmlNetconfConstants.MESSAGE_ID,
"bad-element", XmlNetconfConstants.RPC_KEY));
}
import org.opendaylight.netconf.impl.NetconfServerSession;
import org.opendaylight.netconf.util.mapping.AbstractSingletonNetconfOperation;
import org.opendaylight.yangtools.yang.common.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
LOG.info("Session {} closing", session.getSessionId());
} catch (final Exception e) {
throw new DocumentedException("Unable to properly close session " + getNetconfSessionIdForReporting(), e,
- ErrorType.APPLICATION, DocumentedException.ErrorTag.OPERATION_FAILED, ErrorSeverity.ERROR,
- Map.of(ErrorSeverity.ERROR.toString(), e.getMessage()));
+ ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED, ErrorSeverity.ERROR,
+ // FIXME: i.e. <error>exception.toString()</error>? That looks wrong on a few levels.
+ Map.of(ErrorSeverity.ERROR.elementBody(), e.getMessage()));
}
return document.createElement(XmlNetconfConstants.OK);
}
package org.opendaylight.netconf.impl.mapping.operations;
import org.opendaylight.netconf.api.DocumentedException;
-import org.opendaylight.netconf.api.DocumentedException.ErrorTag;
import org.opendaylight.netconf.api.NetconfMessage;
import org.opendaylight.netconf.api.xml.XmlElement;
import org.opendaylight.netconf.api.xml.XmlNetconfConstants;
import org.opendaylight.netconf.mapping.api.NetconfOperationChainedExecution;
import org.opendaylight.netconf.util.mapping.AbstractSingletonNetconfOperation;
import org.opendaylight.yangtools.yang.common.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.opendaylight.netconf.mapping.api.NetconfOperationService;
import org.opendaylight.netconf.mapping.api.SessionAwareNetconfOperation;
import org.opendaylight.yangtools.yang.common.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
final String messageAsString = XmlUtil.toString(message);
LOG.warn("Unable to handle rpc {} on session {}", messageAsString, session, e);
- final DocumentedException.ErrorTag tag;
- if (e instanceof IllegalArgumentException) {
- tag = DocumentedException.ErrorTag.OPERATION_NOT_SUPPORTED;
- } else {
- tag = DocumentedException.ErrorTag.OPERATION_FAILED;
- }
+ final ErrorTag tag = e instanceof IllegalArgumentException ? ErrorTag.OPERATION_NOT_SUPPORTED
+ : ErrorTag.OPERATION_FAILED;
throw new DocumentedException(
- String.format("Unable to handle rpc %s on session %s", messageAsString, session),
- e, ErrorType.APPLICATION, tag, ErrorSeverity.ERROR, Map.of(tag.toString(), e.getMessage()));
+ String.format("Unable to handle rpc %s on session %s", messageAsString, session), e,
+ ErrorType.APPLICATION, tag, ErrorSeverity.ERROR,
+ // FIXME: i.e. in what namespace are we providing these tags? why is this not just:
+ //
+ // <java-throwable xmlns="org.opendaylight.something">
+ // <message>e.getMessage()</message>
+ // </java-throwable>
+ //
+ // for each place where we are mapping Exception.getMessage() ? We probably do not want to propagate
+ // stack traces out, but suppressed exceptions and causal list might be interesting:
+ //
+ // <java-throwable xmlns="org.opendaylight.something">
+ // <message>reported exception</message>
+ // </java-throwable>
+ // <java-throwable xmlns="org.opendaylight.something">
+ // <message>cause of reported exception</message>
+ // </java-throwable>
+ // <java-throwable xmlns="org.opendaylight.something">
+ // <message>cause of cause of reported exception</message>
+ // </java-throwable>
+ Map.of(tag.elementBody(), e.getMessage()));
} catch (final RuntimeException e) {
throw handleUnexpectedEx("sort", e);
}
private static DocumentedException handleUnexpectedEx(final String op, final Exception exception) {
LOG.error("Unexpected exception during netconf operation {}", op, exception);
return new DocumentedException("Unexpected error",
- ErrorType.APPLICATION, DocumentedException.ErrorTag.OPERATION_FAILED, ErrorSeverity.ERROR,
- Map.of(ErrorSeverity.ERROR.toString(), exception.toString()));
+ ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED, ErrorSeverity.ERROR,
+ // FIXME: i.e. <error>exception.toString()</error>? That looks wrong on a few levels.
+ Map.of(ErrorSeverity.ERROR.elementBody(), exception.toString()));
}
private static Document executeOperationWithHighestPriority(final Document message,
import org.slf4j.LoggerFactory;
public final class DeserializerExceptionHandler implements ChannelHandler {
-
private static final Logger LOG = LoggerFactory.getLogger(DeserializerExceptionHandler.class);
@Override
final Map<String, String> info = new HashMap<>();
info.put("cause", cause.getMessage());
final DocumentedException ex = new DocumentedException(cause.getMessage(),
- ErrorType.RPC, DocumentedException.ErrorTag.MALFORMED_MESSAGE, ErrorSeverity.ERROR, info);
+ ErrorType.RPC, DocumentedException.MALFORMED_MESSAGE, ErrorSeverity.ERROR, info);
SendErrorExceptionUtil.sendErrorMessage(ctx.channel(), ex);
}
import org.opendaylight.netconf.mapping.api.NetconfOperation;
import org.opendaylight.netconf.mapping.api.NetconfOperationChainedExecution;
import org.opendaylight.netconf.mapping.api.NetconfOperationService;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
public void testOnNetconfMessageFail() throws Exception {
final DocumentedException ex = assertThrows(DocumentedException.class,
() -> emptyOperationRouter.onNetconfMessage(TEST_RPC_DOC, null));
- assertEquals(DocumentedException.ErrorTag.OPERATION_NOT_SUPPORTED, ex.getErrorTag());
+ assertEquals(ErrorTag.OPERATION_NOT_SUPPORTED, ex.getErrorTag());
}
@Test
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
import org.opendaylight.yangtools.yang.common.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
public final class NetconfTopologyUtils {
public static DocumentedException createMasterIsDownException(final RemoteDeviceId id, final Exception cause) {
return new DocumentedException(id + ":Master is down. Please try again.", cause,
- ErrorType.APPLICATION, DocumentedException.ErrorTag.OPERATION_FAILED, ErrorSeverity.WARNING);
+ ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED, ErrorSeverity.WARNING);
}
}
import org.opendaylight.netconf.topology.singleton.messages.rpc.InvokeRpcMessageReply;
import org.opendaylight.netconf.topology.singleton.messages.transactions.EmptyReadResponse;
import org.opendaylight.yangtools.yang.common.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
assertTrue("Unexpected cause " + cause, cause instanceof DocumentedException);
final DocumentedException de = (DocumentedException) cause;
assertEquals(ErrorSeverity.WARNING, de.getErrorSeverity());
- assertEquals(DocumentedException.ErrorTag.OPERATION_FAILED, de.getErrorTag());
+ assertEquals(ErrorTag.OPERATION_FAILED, de.getErrorTag());
assertEquals(ErrorType.APPLICATION, de.getErrorType());
}
}
\ No newline at end of file
import org.opendaylight.netconf.topology.singleton.messages.transactions.ReadRequest;
import org.opendaylight.netconf.topology.singleton.messages.transactions.SubmitRequest;
import org.opendaylight.yangtools.yang.common.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
assertTrue("Unexpected cause " + cause, cause instanceof DocumentedException);
final DocumentedException de = (DocumentedException) cause;
assertEquals(ErrorSeverity.WARNING, de.getErrorSeverity());
- assertEquals(DocumentedException.ErrorTag.OPERATION_FAILED, de.getErrorTag());
+ assertEquals(ErrorTag.OPERATION_FAILED, de.getErrorTag());
assertEquals(ErrorType.APPLICATION, de.getErrorType());
}
}
import org.w3c.dom.Element;
public abstract class AbstractLastNetconfOperation extends AbstractNetconfOperation {
-
protected AbstractLastNetconfOperation(final String netconfSessionIdForReporting) {
super(netconfSessionIdForReporting);
}
if (!subsequentOperation.isExecutionTermination()) {
throw new DocumentedException(String.format(
"No netconf operation expected to be subsequent to %s, but is %s", this, subsequentOperation),
- ErrorType.APPLICATION, DocumentedException.ErrorTag.MALFORMED_MESSAGE, ErrorSeverity.ERROR);
+ ErrorType.APPLICATION, DocumentedException.MALFORMED_MESSAGE, ErrorSeverity.ERROR);
}
return handleWithNoSubsequentOperations(document, operationElement);
import org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil;
import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
import org.opendaylight.yangtools.util.concurrent.FluentFutures;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.RpcError;
import org.opendaylight.yangtools.yang.common.RpcResult;
private static RpcResult<NetconfMessage> createErrorRpcResult(final RpcError.ErrorType errorType,
final String message) {
return RpcResultBuilder.<NetconfMessage>failed()
- .withError(errorType, NetconfDocumentedException.ErrorTag.OPERATION_FAILED.getTagValue(), message).build();
+ .withError(errorType, ErrorTag.OPERATION_FAILED.elementBody(), message).build();
}
@Override
import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
import org.opendaylight.mdsal.dom.api.DOMRpcResult;
-import org.opendaylight.netconf.api.DocumentedException;
import org.opendaylight.netconf.api.ModifyAction;
import org.opendaylight.netconf.api.NetconfDocumentedException;
import org.opendaylight.netconf.sal.connect.netconf.util.NetconfBaseOps;
import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
import org.opendaylight.yangtools.yang.common.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.opendaylight.yangtools.yang.common.RpcError;
import org.opendaylight.yangtools.yang.common.RpcResult;
final NetconfDocumentedException exception =
new NetconfDocumentedException(
id + ":RPC during tx returned an exception" + throwable.getMessage(),
+ // FIXME: add proper unmask/wrap to ExecutionException
new Exception(throwable),
- ErrorType.APPLICATION,
- DocumentedException.ErrorTag.OPERATION_FAILED,
- ErrorSeverity.ERROR);
+ ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED, ErrorSeverity.ERROR);
transformed.setException(exception);
}
}, MoreExecutors.directExecutor());
}
}
if (errorsEncouneterd) {
- final NetconfDocumentedException exception = new NetconfDocumentedException(id
- + ":RPC during tx failed. " + msgBuilder.toString(),
- errType,
- DocumentedException.ErrorTag.from(errorTag),
- errSeverity);
+ final NetconfDocumentedException exception = new NetconfDocumentedException(
+ id + ":RPC during tx failed. " + msgBuilder, errType, new ErrorTag(errorTag), errSeverity);
transformed.setException(exception);
return;
}
import org.opendaylight.yangtools.rfc7952.data.util.ImmutableNormalizedMetadata;
import org.opendaylight.yangtools.rfc7952.data.util.ImmutableNormalizedMetadata.Builder;
import org.opendaylight.yangtools.yang.common.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.RpcError;
if (!inputMsgId.equals(outputMsgId)) {
throw new NetconfDocumentedException("Response message contained unknown \"message-id\"", null,
- ErrorType.PROTOCOL, NetconfDocumentedException.ErrorTag.BAD_ATTRIBUTE, ErrorSeverity.ERROR,
+ ErrorType.PROTOCOL, ErrorTag.BAD_ATTRIBUTE, ErrorSeverity.ERROR,
ImmutableMap.of("actual-message-id", outputMsgId, "expected-message-id", inputMsgId));
}
}
}
return ex.getErrorSeverity() == ErrorSeverity.ERROR
- ? RpcResultBuilder.newError(ex.getErrorType().toLegacy(), ex.getErrorTag().getTagValue(),
+ ? RpcResultBuilder.newError(ex.getErrorType().toLegacy(), ex.getErrorTag().elementBody(),
ex.getLocalizedMessage(), null, infoBuilder.toString(), ex.getCause())
: RpcResultBuilder.newWarning(
- ex.getErrorType().toLegacy(), ex.getErrorTag().getTagValue(),
+ ex.getErrorType().toLegacy(), ex.getErrorTag().elementBody(),
ex.getLocalizedMessage(), null, infoBuilder.toString(), ex.getCause());
}
public static RpcResult<NetconfMessage> toRpcResult(final FailedNetconfMessage message) {
return RpcResultBuilder.<NetconfMessage>failed()
.withRpcError(toRpcError(new NetconfDocumentedException(message.getException().getMessage(),
- ErrorType.APPLICATION, DocumentedException.ErrorTag.MALFORMED_MESSAGE, ErrorSeverity.ERROR)))
+ ErrorType.APPLICATION, DocumentedException.MALFORMED_MESSAGE, ErrorSeverity.ERROR)))
.build();
}
}
import org.opendaylight.netconf.mapping.api.NetconfOperation;
import org.opendaylight.netconf.mapping.api.NetconfOperationChainedExecution;
import org.opendaylight.yangtools.yang.common.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.w3c.dom.Document;
return document;
} else if (subsequentOperation.isExecutionTermination()) {
throw new DocumentedException("Mapping not found " + XmlUtil.toString(requestMessage),
- ErrorType.APPLICATION, DocumentedException.ErrorTag.OPERATION_NOT_SUPPORTED, ErrorSeverity.ERROR);
+ ErrorType.APPLICATION, ErrorTag.OPERATION_NOT_SUPPORTED, ErrorSeverity.ERROR);
} else {
return subsequentOperation.execute(requestMessage);
}
import org.opendaylight.netconf.mapping.api.NetconfOperationChainedExecution;
import org.opendaylight.netconf.util.mapping.AbstractNetconfOperation;
import org.opendaylight.yangtools.yang.common.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
throws DocumentedException {
if (subsequentOperation.isExecutionTermination()) {
throw new DocumentedException(String.format("Subsequent netconf operation expected by %s", this),
- ErrorType.APPLICATION, DocumentedException.ErrorTag.OPERATION_FAILED, ErrorSeverity.ERROR);
+ ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED, ErrorSeverity.ERROR);
}
try {
LOG.warn(errorMessage, e);
throw new DocumentedException(errorMessage, e,
- ErrorType.APPLICATION, DocumentedException.ErrorTag.OPERATION_FAILED, ErrorSeverity.ERROR,
- Map.of(ErrorSeverity.ERROR.toString(), e.getMessage()));
+ ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED, ErrorSeverity.ERROR,
+ // FIXME: i.e. <error>e.getMessage()</error> ?
+ Map.of(ErrorSeverity.ERROR.elementBody(), e.getMessage()));
}
}
import org.opendaylight.netconf.mapping.api.NetconfOperation;
import org.opendaylight.netconf.mapping.api.NetconfOperationChainedExecution;
import org.opendaylight.yangtools.yang.common.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.w3c.dom.Document;
return document;
} else if (subsequentOperation.isExecutionTermination()) {
throw new DocumentedException("Mapping not found " + XmlUtil.toString(requestMessage),
- ErrorType.APPLICATION, DocumentedException.ErrorTag.OPERATION_NOT_SUPPORTED, ErrorSeverity.ERROR);
+ ErrorType.APPLICATION, ErrorTag.OPERATION_NOT_SUPPORTED, ErrorSeverity.ERROR);
} else {
return subsequentOperation.execute(requestMessage);
}
import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
import org.opendaylight.mdsal.dom.api.DOMRpcResult;
import org.opendaylight.mdsal.dom.spi.DefaultDOMRpcResult;
-import org.opendaylight.netconf.api.DocumentedException;
import org.opendaylight.netconf.api.NetconfDocumentedException;
import org.opendaylight.netconf.dom.api.NetconfDataTreeService;
import org.opendaylight.yangtools.yang.common.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.opendaylight.yangtools.yang.common.RpcError;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
return operation.get();
} else {
return Futures.immediateFailedFuture(new NetconfDocumentedException("Lock operation failed",
- ErrorType.APPLICATION, DocumentedException.ErrorTag.LOCK_DENIED, ErrorSeverity.ERROR));
+ ErrorType.APPLICATION, ErrorTag.LOCK_DENIED, ErrorSeverity.ERROR));
}
},
MoreExecutors.directExecutor());
ErrorType errType = ErrorType.APPLICATION;
ErrorSeverity errSeverity = ErrorSeverity.ERROR;
StringJoiner msgBuilder = new StringJoiner(" ");
- String errorTag = "operation-failed";
+ ErrorTag errorTag = ErrorTag.OPERATION_FAILED;
for (final RpcError error : errors) {
errType = error.getErrorType().toNetconf();
errSeverity = error.getSeverity().toNetconf();
msgBuilder.add(error.getMessage());
msgBuilder.add(error.getInfo());
- errorTag = error.getTag();
+ errorTag = new ErrorTag(error.getTag());
}
return new TransactionCommitFailedException("Netconf transaction commit failed",
- new NetconfDocumentedException("RPC during tx failed. " + msgBuilder.toString(), errType,
- DocumentedException.ErrorTag.from(errorTag), errSeverity));
+ new NetconfDocumentedException("RPC during tx failed. " + msgBuilder.toString(), errType, errorTag,
+ errSeverity));
}
private static void executeWithLogging(final Supplier<ListenableFuture<? extends DOMRpcResult>> operation) {
import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
import org.opendaylight.restconf.common.errors.RestconfError;
import org.opendaylight.restconf.nb.rfc8040.rests.transactions.RestconfStrategy;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.opendaylight.yangtools.yang.common.RpcError;
import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
final List<Throwable> causalChain = Throwables.getCausalChain(cause);
for (Throwable error : causalChain) {
if (error instanceof DocumentedException) {
- final DocumentedException.ErrorTag errorTag = ((DocumentedException) error).getErrorTag();
- if (errorTag.equals(DocumentedException.ErrorTag.DATA_EXISTS)) {
+ final ErrorTag errorTag = ((DocumentedException) error).getErrorTag();
+ if (errorTag.equals(ErrorTag.DATA_EXISTS)) {
LOG.trace("Operation via Restconf was not executed because data at {} already exists",
path);
throw new RestconfDocumentedException(e, new RestconfError(ErrorType.PROTOCOL,
RestconfError.ErrorTag.DATA_EXISTS, "Data already exists", path));
- } else if (errorTag.equals(DocumentedException.ErrorTag.DATA_MISSING)) {
+ } else if (errorTag.equals(ErrorTag.DATA_MISSING)) {
LOG.trace("Operation via Restconf was not executed because data at {} does not exist",
path);
throw new RestconfDocumentedException(e, new RestconfError(ErrorType.PROTOCOL,
throw new RestconfDocumentedException(error.getMessage(),
((NetconfDocumentedException) error).getErrorType(),
RestconfError.ErrorTag.valueOfCaseInsensitive(
- ((NetconfDocumentedException) error).getErrorTag().getTagValue()), e);
+ ((NetconfDocumentedException) error).getErrorTag().elementBody()), e);
}
}
import org.opendaylight.mdsal.dom.api.DOMDataBroker;
import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
import org.opendaylight.mdsal.dom.spi.DefaultDOMRpcResult;
-import org.opendaylight.netconf.api.DocumentedException;
import org.opendaylight.netconf.api.NetconfDocumentedException;
import org.opendaylight.netconf.dom.api.NetconfDataTreeService;
import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
-import org.opendaylight.restconf.common.errors.RestconfError.ErrorTag;
+import org.opendaylight.restconf.common.errors.RestconfError;
import org.opendaylight.restconf.nb.rfc8040.rests.transactions.MdsalRestconfStrategy;
import org.opendaylight.restconf.nb.rfc8040.rests.transactions.NetconfRestconfStrategy;
import org.opendaylight.restconf.nb.rfc8040.rests.transactions.RestconfStrategy;
import org.opendaylight.yangtools.yang.common.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
when(readWrite.exists(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.empty()))
.thenReturn(immediateFalseFluentFuture());
final NetconfDocumentedException exception = new NetconfDocumentedException("id",
- ErrorType.RPC, DocumentedException.ErrorTag.from("data-missing"), ErrorSeverity.ERROR);
+ ErrorType.RPC, ErrorTag.DATA_MISSING, ErrorSeverity.ERROR);
final SettableFuture<? extends CommitInfo> ret = SettableFuture.create();
ret.setException(new TransactionCommitFailedException(
String.format("Commit of transaction %s failed", this), exception));
fail("Delete operation should fail due to missing data");
} catch (final RestconfDocumentedException e) {
assertEquals(ErrorType.PROTOCOL, e.getErrors().get(0).getErrorType());
- assertEquals(ErrorTag.DATA_MISSING, e.getErrors().get(0).getErrorTag());
+ assertEquals(RestconfError.ErrorTag.DATA_MISSING, e.getErrors().get(0).getErrorTag());
}
}
}
import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
import org.opendaylight.mdsal.dom.api.DOMRpcResult;
import org.opendaylight.mdsal.dom.spi.DefaultDOMRpcResult;
-import org.opendaylight.netconf.api.DocumentedException;
import org.opendaylight.netconf.api.NetconfDocumentedException;
import org.opendaylight.netconf.dom.api.NetconfDataTreeService;
import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
import org.opendaylight.restconf.nb.rfc8040.rests.transactions.NetconfRestconfStrategy;
import org.opendaylight.restconf.nb.rfc8040.rests.transactions.RestconfStrategy;
import org.opendaylight.yangtools.yang.common.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
doReturn(immediateFalseFluentFuture()).when(this.rwTransaction).exists(LogicalDatastoreType.CONFIGURATION,
this.targetNodeForCreateAndDelete);
final NetconfDocumentedException exception = new NetconfDocumentedException("id",
- ErrorType.RPC, DocumentedException.ErrorTag.from("data-missing"), ErrorSeverity.ERROR);
+ ErrorType.RPC, ErrorTag.DATA_MISSING, ErrorSeverity.ERROR);
final SettableFuture<? extends DOMRpcResult> ret = SettableFuture.create();
ret.setException(new TransactionCommitFailedException(
String.format("Commit of transaction %s failed", this), exception));