Use requested media type in RestconfDocumentedExceptionMapper
[netconf.git] / restconf / restconf-nb-bierman02 / src / main / java / org / opendaylight / netconf / sal / rest / impl / RestconfDocumentedExceptionMapper.java
index 459078262147cc42a187868a3ddfd96de8184b98..9f25da0f0c9f421d08bca6871f2a5222fe5909ab 100644 (file)
@@ -15,8 +15,10 @@ import com.google.gson.stream.JsonWriter;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
 import java.net.URI;
 import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 import javax.ws.rs.core.Context;
@@ -32,10 +34,10 @@ import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamWriter;
 import org.opendaylight.netconf.sal.rest.api.Draft02;
 import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
-import org.opendaylight.netconf.sal.restconf.impl.InstanceIdentifierContext;
-import org.opendaylight.netconf.sal.restconf.impl.NormalizedNodeContext;
-import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException;
-import org.opendaylight.netconf.sal.restconf.impl.RestconfError;
+import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
+import org.opendaylight.restconf.common.context.NormalizedNodeContext;
+import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
+import org.opendaylight.restconf.common.errors.RestconfError;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
@@ -87,24 +89,26 @@ public class RestconfDocumentedExceptionMapper implements ExceptionMapper<Restco
     @Context
     private HttpHeaders headers;
 
+    private final ControllerContext controllerContext;
+
+    public RestconfDocumentedExceptionMapper(ControllerContext controllerContext) {
+        this.controllerContext = Preconditions.checkNotNull(controllerContext);
+    }
+
     @Override
     public Response toResponse(final RestconfDocumentedException exception) {
 
         LOG.debug("In toResponse: {}", exception.getMessage());
 
-        final List<MediaType> accepts = headers.getAcceptableMediaTypes();
-        accepts.remove(MediaType.WILDCARD_TYPE);
-
-        LOG.debug("Accept headers: {}", accepts);
-
-        final MediaType mediaType;
-        if (accepts != null && accepts.size() > 0) {
-            mediaType = accepts.get(0); // just pick the first one
-        } else {
-            // Default to the content type if there's no Accept header
-            mediaType = MediaType.APPLICATION_JSON_TYPE;
+        final List<MediaType> mediaTypeList = new ArrayList<>();
+        if (headers.getMediaType() != null) {
+            mediaTypeList.add(headers.getMediaType());
         }
 
+        mediaTypeList.addAll(headers.getAcceptableMediaTypes());
+        final MediaType mediaType = mediaTypeList.stream().filter(type -> !type.equals(MediaType.WILDCARD_TYPE))
+                .findFirst().orElse(MediaType.APPLICATION_JSON_TYPE);
+
         LOG.debug("Using MediaType: {}", mediaType);
 
         final List<RestconfError> errors = exception.getErrors();
@@ -118,8 +122,8 @@ public class RestconfDocumentedExceptionMapper implements ExceptionMapper<Restco
 
         final int status = errors.iterator().next().getErrorTag().getStatusCode();
 
-        final ControllerContext context = ControllerContext.getInstance();
-        final DataNodeContainer errorsSchemaNode = (DataNodeContainer) context.getRestconfModuleErrorsSchemaNode();
+        final DataNodeContainer errorsSchemaNode =
+                (DataNodeContainer) controllerContext.getRestconfModuleErrorsSchemaNode();
 
         if (errorsSchemaNode == null) {
             return Response.status(status).type(MediaType.TEXT_PLAIN_TYPE).entity(exception.getMessage()).build();
@@ -145,7 +149,7 @@ public class RestconfDocumentedExceptionMapper implements ExceptionMapper<Restco
         errContBuild.withChild(listErorsBuilder.build());
 
         final NormalizedNodeContext errContext =  new NormalizedNodeContext(new InstanceIdentifierContext<>(null,
-                (DataSchemaNode) errorsSchemaNode, null, context.getGlobalSchema()), errContBuild.build());
+                (DataSchemaNode) errorsSchemaNode, null, controllerContext.getGlobalSchema()), errContBuild.build());
 
         Object responseBody;
         if (mediaType.getSubtype().endsWith("json")) {
@@ -274,8 +278,12 @@ public class RestconfDocumentedExceptionMapper implements ExceptionMapper<Restco
             LOG.warn("Error writing error response body", e);
         }
 
-        return outStream.toString();
-
+        try {
+            return outStream.toString(StandardCharsets.UTF_8.name());
+        } catch (UnsupportedEncodingException e) {
+            // Shouldn't happen
+            return "Failure encoding error response: " + e;
+        }
     }
 
     private static Object toXMLResponseBody(final NormalizedNodeContext errorsNode,
@@ -350,7 +358,12 @@ public class RestconfDocumentedExceptionMapper implements ExceptionMapper<Restco
             LOG.warn("Error writing error response body.", e);
         }
 
-        return outStream.toString();
+        try {
+            return outStream.toString(StandardCharsets.UTF_8.name());
+        } catch (UnsupportedEncodingException e) {
+            // Shouldn't happen
+            return "Failure encoding error response: " + e;
+        }
     }
 
     private static void writeRootElement(final XMLStreamWriter xmlWriter, final NormalizedNodeWriter nnWriter,