use of com.linkedin.restli.common.ContentType in project rest.li by linkedin.
the class TestContentType method testNullContentType.
@Test
public void testNullContentType() throws MimeTypeParseException {
ContentType contentType = ContentType.getContentType(null).get();
// default to JSON for null content-type
Assert.assertEquals(ContentType.JSON, contentType);
}
use of com.linkedin.restli.common.ContentType in project rest.li by linkedin.
the class TestContentType method testGetRequestNullContentType.
@Test
public void testGetRequestNullContentType() throws MimeTypeParseException {
ContentType contentType = ContentType.getRequestContentType(null, TEST_URI).get();
Assert.assertEquals(ContentType.JSON, contentType);
}
use of com.linkedin.restli.common.ContentType in project rest.li by linkedin.
the class RestLiSymbolTableRequestHandler method handleRequest.
@Override
public void handleRequest(RestRequest request, RequestContext requestContext, Callback<RestResponse> callback) {
if (HttpMethod.GET != HttpMethod.valueOf(request.getMethod())) {
LOGGER.error("GET is expected, but " + request.getMethod() + " received");
callback.onError(RestException.forError(HttpStatus.S_405_METHOD_NOT_ALLOWED.getCode(), "Invalid method"));
return;
}
//
// Determine response content type based on accept header.
// Assume protobuf2 if no accept header is specified. Note that this is a deviation from the rest of rest.li
// which assumes JSON as the default, for efficiency reasons.
//
ContentType type;
String mimeType = Optional.ofNullable(request.getHeader(RestConstants.HEADER_ACCEPT)).orElse(RestConstants.HEADER_VALUE_APPLICATION_PROTOBUF2);
try {
type = ContentType.getContentType(mimeType).orElseThrow(() -> new MimeTypeParseException("Invalid accept type: " + mimeType));
} catch (MimeTypeParseException e) {
LOGGER.error("Could not handle accept type", e);
callback.onError(RestException.forError(HttpStatus.S_406_NOT_ACCEPTABLE.getCode(), "Invalid accept type: " + mimeType));
return;
}
final String path = request.getURI().getRawPath();
final List<UriComponent.PathSegment> pathSegments = UriComponent.decodePath(path, true);
final SymbolTableProvider provider = SymbolTableProviderHolder.INSTANCE.getSymbolTableProvider();
SymbolTable symbolTable = null;
// at this point, `handleRequest` has verified that the incoming request is a symbolTable request.
// The URL can be one of two options:
// .../symbolTable/tableName
// .../symbolTable
// We check if the last path segments is "symbolTable", and if it is, we call provider.getResponseSymbolTable
// because we do not know the table name.
// Otherwise, we call provider.getSymbolTable
int pathSize = pathSegments.size();
try {
if (pathSegments.get(pathSize - 1).getPath().equals(SYMBOL_TABLE_URI_PATH)) {
symbolTable = provider.getResponseSymbolTable(request.getURI(), request.getHeaders());
} else if (pathSegments.get(pathSize - 2).getPath().equals(SYMBOL_TABLE_URI_PATH)) {
symbolTable = provider.getSymbolTable(pathSegments.get(pathSize - 1).getPath());
} else {
LOGGER.error("request is malformed for handling symbolTable" + request.getURI());
}
} catch (IllegalStateException e) {
LOGGER.error("Exception retrieving symbol table for URI " + request.getURI());
symbolTable = null;
}
if (symbolTable == null) {
LOGGER.error("Did not find symbol table for path " + path);
callback.onError(RestException.forError(HttpStatus.S_404_NOT_FOUND.getCode(), "Did not find symbol table"));
return;
}
try {
// Cache key is the name of the symbol table concatenated with the type used to serialize the payload.
String cacheKey = symbolTable.getName() + ":" + type.getHeaderKey();
ByteString serializedTable = _symbolTableNameToSerializedBytesCache.getIfPresent(cacheKey);
if (serializedTable == null) {
serializedTable = SymbolTableSerializer.toByteString(type.getCodec(), symbolTable);
_symbolTableNameToSerializedBytesCache.put(cacheKey, serializedTable);
}
RestResponse restResponse = new RestResponseBuilder().setStatus(HttpStatus.S_200_OK.getCode()).setHeader(RestConstants.HEADER_CONTENT_TYPE, type.getHeaderKey()).setEntity(serializedTable).build();
callback.onSuccess(restResponse);
} catch (IOException e) {
callback.onError(e);
}
}
use of com.linkedin.restli.common.ContentType in project rest.li by linkedin.
the class ResponseUtils method encodeResult.
private static RestResponseBuilder encodeResult(String mimeType, URI requestUri, Map<String, String> requestHeaders, RestResponseBuilder builder, DataMap dataMap) {
try {
ContentType type = ContentType.getResponseContentType(mimeType, requestUri, requestHeaders).orElseThrow(() -> new RestLiServiceException(HttpStatus.S_406_NOT_ACCEPTABLE, "Requested mime type for encoding is not supported. Mimetype: " + mimeType));
assert type != null;
builder.setHeader(RestConstants.HEADER_CONTENT_TYPE, type.getHeaderKey());
builder.setEntity(DataMapUtils.mapToByteString(dataMap, type.getCodec()));
} catch (MimeTypeParseException e) {
throw new RestLiServiceException(HttpStatus.S_406_NOT_ACCEPTABLE, "Invalid mime type: " + mimeType);
}
return builder;
}
use of com.linkedin.restli.common.ContentType in project rest.li by linkedin.
the class StreamRestLiServer method handleStructuredDataResourceRequest.
private void handleStructuredDataResourceRequest(StreamRequest request, RoutingResult routingResult, Callback<?> callback, Function<ContentType, Callback<RestLiResponse>> restLiResponseCallbackConstructor, Consumer<RestRequest> fallbackRequestProcessor) {
ContentType reqContentType, respContentType;
try {
// TODO: We should throw exception instead of defaulting to JSON when the request content type is non-null and
// unrecognized. This behavior was inadvertently changed in commit d149605e4181349b64180bdfe0b4d24a294dc6f6
// when this logic was moved from DataMapUtils.readMapWithExceptions() to DataMapConverter.dataMapToByteString().
reqContentType = ContentType.getContentType(request.getHeader(RestConstants.HEADER_CONTENT_TYPE)).orElse(ContentType.JSON);
String respMimeType = routingResult.getContext().getResponseMimeType();
respContentType = ContentType.getResponseContentType(respMimeType, request.getURI(), request.getHeaders()).orElseThrow(() -> new RestLiServiceException(HttpStatus.S_406_NOT_ACCEPTABLE, "Requested mime type for encoding is not supported. Mimetype: " + respMimeType));
} catch (MimeTypeParseException e) {
callback.onError(e);
return;
}
StreamDataCodec reqCodec = reqContentType.getStreamCodec();
StreamDataCodec respCodec = respContentType.getStreamCodec();
if (_useStreamCodec && reqCodec != null && respCodec != null) {
final RequestContext requestContext = routingResult.getContext().getRawRequestContext();
TimingContextUtil.beginTiming(requestContext, FrameworkTimingKeys.SERVER_REQUEST_RESTLI_DESERIALIZATION.key());
reqCodec.decodeMap(EntityStreamAdapters.toGenericEntityStream(request.getEntityStream())).handle((dataMap, e) -> {
TimingContextUtil.endTiming(requestContext, FrameworkTimingKeys.SERVER_REQUEST_RESTLI_DESERIALIZATION.key());
Throwable error = null;
if (e == null) {
try {
handleResourceRequest(request, routingResult, dataMap, restLiResponseCallbackConstructor.apply(respContentType));
} catch (Throwable throwable) {
error = throwable;
}
} else {
error = buildPreRoutingStreamException(new RoutingException("Cannot parse request entity", HttpStatus.S_400_BAD_REQUEST.getCode(), e), request);
}
if (error != null) {
log.error("Fail to handle structured stream request", error);
callback.onError(error);
}
// handle function requires a return statement although there is no more completion stage.
return null;
});
} else {
// Fallback to fully-buffered request and response processing.
Messages.toRestRequest(request).handle((restRequest, e) -> {
if (e == null) {
try {
fallbackRequestProcessor.accept(restRequest);
} catch (Throwable throwable) {
e = throwable;
}
}
if (e != null) {
log.error("Fail to handle structured toRest request", e);
callback.onError(e);
}
// handle function requires a return statement although there is no more completion stage.
return null;
});
}
}
Aggregations