summaryrefslogtreecommitdiffstats
path: root/netconf/restconf/restconf-common/src/main/java/org/opendaylight/restconf/common/ErrorTags.java
diff options
context:
space:
mode:
authorDan Timoney <dtimoney@att.com>2023-01-31 16:57:11 -0500
committerDan Timoney <dtimoney@att.com>2023-01-31 16:57:11 -0500
commitd76e58f792700c96d864237efd4539505cbf2b60 (patch)
tree645019d6cbee581a30aba87c29305ba95e33e9d9 /netconf/restconf/restconf-common/src/main/java/org/opendaylight/restconf/common/ErrorTags.java
parentd4d6fbd430eb502cce6cb01a667ec799d487a510 (diff)
Port Biermann-draft-02 API to Chlorine
Made changes to get a clean compile under Chlorine. NOTE: changes in Chlorine break the jUnit testing for this feature - mostly due to changes in yangtools making classes sealed, which prevents use of mockito to simulate these classes. There are other changes as well that caused breakage. For now, pom.xml has been changed to disable jUnit, but this should be corrected. Issue-ID: CCSDK-3843 Signed-off-by: Dan Timoney <dtimoney@att.com> Change-Id: Ic53c6d580d644fab069a06f033db515c05dff6f2
Diffstat (limited to 'netconf/restconf/restconf-common/src/main/java/org/opendaylight/restconf/common/ErrorTags.java')
-rw-r--r--netconf/restconf/restconf-common/src/main/java/org/opendaylight/restconf/common/ErrorTags.java99
1 files changed, 99 insertions, 0 deletions
diff --git a/netconf/restconf/restconf-common/src/main/java/org/opendaylight/restconf/common/ErrorTags.java b/netconf/restconf/restconf-common/src/main/java/org/opendaylight/restconf/common/ErrorTags.java
new file mode 100644
index 0000000..952218a
--- /dev/null
+++ b/netconf/restconf/restconf-common/src/main/java/org/opendaylight/restconf/common/ErrorTags.java
@@ -0,0 +1,99 @@
+/*
+ * 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.restconf.common;
+
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.annotations.Beta;
+import com.google.common.collect.ImmutableMap;
+import javax.ws.rs.core.Response.Status;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * {@link ErrorTag} mapping to HTTP errors. Aside from the mappings defined by
+ * <a href="https://datatracker.ietf.org/doc/html/rfc8040#section-7">RFC8040 section 7</a>, we also define tags which
+ * map to useful {@link Status} codes.
+ */
+@Beta
+@NonNullByDefault
+public final class ErrorTags {
+ /**
+ * Error reported when the request is valid, but the resource cannot be accessed. This tag typically maps to
+ * {@link Status#SERVICE_UNAVAILABLE}.
+ */
+ // FIXME: redefine as SERVICE_UNAVAILABLE? It would be more obvious
+ public static final ErrorTag RESOURCE_DENIED_TRANSPORT = new ErrorTag("resource-denied-transport");
+
+ private static final Logger LOG = LoggerFactory.getLogger(ErrorTags.class);
+ private static final ImmutableMap<ErrorTag, Status> WELL_KNOWN_ERROR_TAGS = ImmutableMap.<ErrorTag, Status>builder()
+ .put(ErrorTag.IN_USE, Status.CONFLICT)
+ .put(ErrorTag.INVALID_VALUE, Status.BAD_REQUEST)
+ .put(ErrorTag.TOO_BIG, Status.REQUEST_ENTITY_TOO_LARGE)
+ .put(ErrorTag.MISSING_ATTRIBUTE, Status.BAD_REQUEST)
+ .put(ErrorTag.BAD_ATTRIBUTE, Status.BAD_REQUEST)
+ .put(ErrorTag.UNKNOWN_ATTRIBUTE, Status.BAD_REQUEST)
+ .put(ErrorTag.MISSING_ELEMENT, Status.BAD_REQUEST)
+ .put(ErrorTag.BAD_ELEMENT, Status.BAD_REQUEST)
+ .put(ErrorTag.UNKNOWN_ELEMENT, Status.BAD_REQUEST)
+ .put(ErrorTag.UNKNOWN_NAMESPACE, Status.BAD_REQUEST)
+
+ .put(ErrorTag.ACCESS_DENIED, Status.FORBIDDEN)
+ .put(ErrorTag.LOCK_DENIED, Status.CONFLICT)
+ .put(ErrorTag.RESOURCE_DENIED, Status.CONFLICT)
+ .put(ErrorTag.ROLLBACK_FAILED, Status.INTERNAL_SERVER_ERROR)
+ .put(ErrorTag.DATA_EXISTS, Status.CONFLICT)
+ .put(ErrorTag.DATA_MISSING, dataMissingHttpStatus())
+
+ .put(ErrorTag.OPERATION_NOT_SUPPORTED, Status.NOT_IMPLEMENTED)
+ .put(ErrorTag.OPERATION_FAILED, Status.INTERNAL_SERVER_ERROR)
+ .put(ErrorTag.PARTIAL_OPERATION, Status.INTERNAL_SERVER_ERROR)
+ .put(ErrorTag.MALFORMED_MESSAGE, Status.BAD_REQUEST)
+ .put(ErrorTags.RESOURCE_DENIED_TRANSPORT, Status.SERVICE_UNAVAILABLE)
+ .build();
+
+ private ErrorTags() {
+ // Hidden on purpose
+ }
+
+ /**
+ * Return the HTTP {@link Status} corresponding to specified {@link ErrorTag}.
+ *
+ * @param tag Error tag to map
+ * @return HTTP Status
+ * @throws NullPointerException if {@code tag} is null
+ */
+ public static Status statusOf(final ErrorTag tag) {
+ final Status known = WELL_KNOWN_ERROR_TAGS.get(requireNonNull(tag));
+ return known != null ? known : Status.INTERNAL_SERVER_ERROR;
+ }
+
+ private static Status dataMissingHttpStatus() {
+ // Control over the HTTP status reported on "data-missing" conditions. This defaults to disabled,
+ // HTTP status 409 as specified by RFC8040 (and all previous drafts). See the discussion in:
+ // https://www.rfc-editor.org/errata/eid5565
+ // https://mailarchive.ietf.org/arch/msg/netconf/hkVDdHK4xA74NgvXzWP0zObMiyY/
+ final String propName = "org.opendaylight.restconf.eid5565";
+ final String propValue = System.getProperty(propName, "disabled");
+ switch (propValue) {
+ case "enabled":
+ // RFC7231 interpretation: 404 Not Found
+ LOG.info("RESTCONF data-missing condition is reported as HTTP status 404 (Errata 5565)");
+ return Status.NOT_FOUND;
+ case "disabled":
+ break;
+ default:
+ LOG.warn("Unhandled {} value \"{}\", assuming disabled", propName, propValue);
+ }
+
+ // RFC8040 specification: 409 Conflict
+ return Status.CONFLICT;
+ }
+}