*/
package org.opendaylight.restconf.nb.rfc8040.legacy;
-import static java.util.Objects.requireNonNull;
-
-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://www.rfc-editor.org/rfc/rfc8040#section-7">RFC8040 section 7</a>, we also define tags which
- * map to useful {@link Status} codes.
+ * Additional {@link ErrorTag}s.
*/
@NonNullByDefault
public final class ErrorTags {
// 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 var 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 var propName = "org.opendaylight.restconf.eid5565";
- final var 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;
- }
}