ContentTypeValidationDirective { public static Route ensureValidContentType(final Set<String> supportedMediaTypes, final RequestContext ctx, final DittoHeaders dittoHeaders, final Supplier<Route> inner) { final String requestsMediaType = extractMediaType(ctx.getRequest()); if (supportedMediaTypes.contains(requestsMediaType)) { return inner.get(); } else { if (LOGGER.isInfoEnabled()) { LOGGER.withCorrelationId(dittoHeaders) .info("Request rejected: unsupported media-type: <{}> request: <{}>", requestsMediaType, requestToLogString(ctx.getRequest())); } throw UnsupportedMediaTypeException .withDetailedInformationBuilder(requestsMediaType, supportedMediaTypes) .dittoHeaders(dittoHeaders) .build(); } } private  ContentTypeValidationDirective(); static Route ensureValidContentType(final Set<String> supportedMediaTypes,
             final RequestContext ctx,
             final DittoHeaders dittoHeaders,
             final Supplier<Route> inner);  }
@Test public void testValidContentType() { final DittoHeaders dittoHeaders = DittoHeaders.empty(); final ContentType type = ContentTypes.APPLICATION_JSON; final TestRouteResult result = testRoute(extractRequestContext( ctx -> ensureValidContentType(Set.of(type.mediaType().toString()), ctx, dittoHeaders, COMPLETE_OK))) .run(HttpRequest.PUT("someUrl").withEntity(type, "something".getBytes())); result.assertStatusCode(StatusCodes.OK); }
@Test public void testNonValidContentType() { final DittoHeaders dittoHeaders = DittoHeaders.empty(); final String type = MediaTypes.APPLICATION_JSON.toString(); final ContentType differentType = ContentTypes.APPLICATION_X_WWW_FORM_URLENCODED; final RequestContext mockedCtx = mock(RequestContext.class); when(mockedCtx.getRequest()) .thenReturn(HttpRequest.PUT("someUrl").withEntity(differentType,"something".getBytes())); final UnsupportedMediaTypeException result = catchThrowableOfType(() -> ensureValidContentType(Set.of(type), mockedCtx, dittoHeaders, COMPLETE_OK), UnsupportedMediaTypeException.class); assertThat(result).hasMessageContaining(differentType.toString()); assertThat(result.getStatusCode()).isEqualTo(HttpStatusCode.UNSUPPORTED_MEDIA_TYPE); }
@Test public void testWithContentTypeWithoutCharset() { final DittoHeaders dittoHeaders = DittoHeaders.empty(); final String type = MediaTypes.TEXT_PLAIN.toString(); final ContentType typeMissingCharset = MediaTypes.TEXT_PLAIN.toContentTypeWithMissingCharset(); final TestRouteResult result = testRoute(extractRequestContext( ctx -> ensureValidContentType(Set.of(type), ctx, dittoHeaders, COMPLETE_OK))) .run(HttpRequest.PUT("someUrl").withEntity(typeMissingCharset, "something".getBytes())); result.assertStatusCode(StatusCodes.OK); }
@Test public void testWithoutEntityNoNPEExpected() { final DittoHeaders dittoHeaders = DittoHeaders.empty(); final String type = ContentTypes.APPLICATION_JSON.mediaType().toString(); final RequestContext mockedCtx = mock(RequestContext.class); when(mockedCtx.getRequest()).thenReturn(HttpRequest.PUT("someUrl")); final UnsupportedMediaTypeException result = catchThrowableOfType(() -> ensureValidContentType(Set.of(type), mockedCtx, dittoHeaders, COMPLETE_OK), UnsupportedMediaTypeException.class); assertThat(result.getStatusCode()).isEqualTo(HttpStatusCode.UNSUPPORTED_MEDIA_TYPE); }
@Test public void testExceptionContainsDittoHeaders() { final DittoHeaders dittoHeaders = DittoHeaders.of(Map.of("someHeaderKey", "someHeaderVal")); final String type = ContentTypes.APPLICATION_JSON.mediaType().toString(); final RequestContext mockedCtx = mock(RequestContext.class); when(mockedCtx.getRequest()).thenReturn(HttpRequest.PUT("someUrl")); final UnsupportedMediaTypeException result = catchThrowableOfType(() -> ensureValidContentType(Set.of(type), mockedCtx, dittoHeaders, COMPLETE_OK), UnsupportedMediaTypeException.class); assertThat(result.getDittoHeaders()).isEqualTo(dittoHeaders); }
@Test public void testWithNonParsableContentType() { final DittoHeaders dittoHeaders = DittoHeaders.empty(); final String nonParsableMediaType = "application-json"; final TestRouteResult result = testRoute(extractRequestContext( ctx -> ensureValidContentType(Set.of(nonParsableMediaType), ctx, dittoHeaders, COMPLETE_OK))) .run(HttpRequest.PUT("someUrl") .addHeader(HttpHeader.parse("content-type", nonParsableMediaType)) .withEntity(ContentTypes.APPLICATION_OCTET_STREAM, "something".getBytes())); result.assertStatusCode(StatusCodes.OK); }
@Test public void testWithUpperCaseContentTypeHeaderName() { final DittoHeaders dittoHeaders = DittoHeaders.empty(); final String type = MediaTypes.APPLICATION_JSON.toString(); final TestRouteResult result = testRoute(extractRequestContext( ctx -> ensureValidContentType(Set.of(type), ctx, dittoHeaders, COMPLETE_OK))) .run(HttpRequest.PUT("someUrl") .addHeader(HttpHeader.parse("CONTENT-TYPE", type)) .withEntity(ContentTypes.APPLICATION_OCTET_STREAM, "something".getBytes())); result.assertStatusCode(StatusCodes.OK); }