use of com.linkedin.restli.server.RestLiServiceException in project rest.li by linkedin.
the class RestLiFilterResponseContextFactory method fromThrowable.
/**
* Create a {@link FilterResponseContext} based on the given error.
*
* @param throwable Error obtained from the resource method invocation.
*
* @return {@link FilterResponseContext} corresponding to the given input.
*/
public FilterResponseContext fromThrowable(Throwable throwable) {
RestLiServiceException restLiServiceException;
if (throwable instanceof RestLiServiceException) {
restLiServiceException = (RestLiServiceException) throwable;
} else if (throwable instanceof RoutingException) {
RoutingException routingException = (RoutingException) throwable;
restLiServiceException = new RestLiServiceException(HttpStatus.fromCode(routingException.getStatus()), routingException.getMessage(), routingException);
} else {
restLiServiceException = new RestLiServiceException(HttpStatus.S_500_INTERNAL_SERVER_ERROR, throwable.getMessage(), throwable);
}
Map<String, String> requestHeaders = _request.getHeaders();
Map<String, String> headers = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
headers.put(RestConstants.HEADER_RESTLI_PROTOCOL_VERSION, ProtocolVersionUtil.extractProtocolVersion(requestHeaders).toString());
headers.put(HeaderUtil.getErrorResponseHeaderName(requestHeaders), RestConstants.HEADER_VALUE_ERROR);
final RestLiResponseData responseData = _responseHandler.buildExceptionResponseData(_request, _method, restLiServiceException, headers, Collections.<HttpCookie>emptyList());
return new FilterResponseContext() {
@Override
public RestLiResponseData getResponseData() {
return responseData;
}
};
}
use of com.linkedin.restli.server.RestLiServiceException in project rest.li by linkedin.
the class ArgumentBuilder method buildArgs.
/**
* Build arguments for resource method invocation. Combines various types of arguments
* into a single array.
*
* @param positionalArguments pass-through arguments coming from
* {@link RestLiArgumentBuilder}
* @param resourceMethod the resource method
* @param context {@link ResourceContext}
* @param template {@link DynamicRecordTemplate}
* @return array of method argument for method invocation.
*/
@SuppressWarnings("deprecation")
public static Object[] buildArgs(final Object[] positionalArguments, final ResourceMethodDescriptor resourceMethod, final ResourceContext context, final DynamicRecordTemplate template) {
List<Parameter<?>> parameters = resourceMethod.getParameters();
Object[] arguments = Arrays.copyOf(positionalArguments, parameters.size());
fixUpComplexKeySingletonArraysInArguments(arguments);
boolean attachmentsDesired = false;
for (int i = positionalArguments.length; i < parameters.size(); ++i) {
Parameter<?> param = parameters.get(i);
try {
if (param.getParamType() == Parameter.ParamType.KEY || param.getParamType() == Parameter.ParamType.ASSOC_KEY_PARAM) {
Object value = context.getPathKeys().get(param.getName());
if (value != null) {
arguments[i] = value;
continue;
}
} else if (param.getParamType() == Parameter.ParamType.CALLBACK) {
continue;
} else if (param.getParamType() == Parameter.ParamType.PARSEQ_CONTEXT_PARAM || param.getParamType() == Parameter.ParamType.PARSEQ_CONTEXT) {
// don't know what to fill in yet
continue;
} else if (param.getParamType() == Parameter.ParamType.HEADER) {
HeaderParam headerParam = param.getAnnotations().get(HeaderParam.class);
String value = context.getRequestHeaders().get(headerParam.value());
arguments[i] = value;
continue;
} else //we must evaluate based on the param type (annotation used)
if (param.getParamType() == Parameter.ParamType.PROJECTION || param.getParamType() == Parameter.ParamType.PROJECTION_PARAM) {
arguments[i] = context.getProjectionMask();
continue;
} else if (param.getParamType() == Parameter.ParamType.METADATA_PROJECTION_PARAM) {
arguments[i] = context.getMetadataProjectionMask();
continue;
} else if (param.getParamType() == Parameter.ParamType.PAGING_PROJECTION_PARAM) {
arguments[i] = context.getPagingProjectionMask();
continue;
} else if (param.getParamType() == Parameter.ParamType.CONTEXT || param.getParamType() == Parameter.ParamType.PAGING_CONTEXT_PARAM) {
PagingContext ctx = RestUtils.getPagingContext(context, (PagingContext) param.getDefaultValue());
arguments[i] = ctx;
continue;
} else if (param.getParamType() == Parameter.ParamType.PATH_KEYS || param.getParamType() == Parameter.ParamType.PATH_KEYS_PARAM) {
arguments[i] = context.getPathKeys();
continue;
} else if (param.getParamType() == Parameter.ParamType.PATH_KEY_PARAM) {
Object value = context.getPathKeys().get(param.getName());
if (value != null) {
arguments[i] = value;
continue;
}
} else if (param.getParamType() == Parameter.ParamType.RESOURCE_CONTEXT || param.getParamType() == Parameter.ParamType.RESOURCE_CONTEXT_PARAM) {
arguments[i] = context;
continue;
} else if (param.getParamType() == Parameter.ParamType.VALIDATOR_PARAM) {
RestLiDataValidator validator = new RestLiDataValidator(resourceMethod.getResourceModel().getResourceClass().getAnnotations(), resourceMethod.getResourceModel().getValueClass(), resourceMethod.getMethodType());
arguments[i] = validator;
continue;
} else if (param.getParamType() == Parameter.ParamType.RESTLI_ATTACHMENTS_PARAM) {
arguments[i] = ((ServerResourceContext) context).getRequestAttachmentReader();
attachmentsDesired = true;
continue;
} else if (param.getParamType() == Parameter.ParamType.POST) {
// handle action parameters
if (template != null) {
DataMap data = template.data();
if (data.containsKey(param.getName())) {
arguments[i] = template.getValue(param);
continue;
}
}
} else if (param.getParamType() == Parameter.ParamType.QUERY) {
Object value;
if (DataTemplate.class.isAssignableFrom(param.getType())) {
value = buildDataTemplateArgument(context, param);
} else {
value = buildRegularArgument(context, param);
}
if (value != null) {
arguments[i] = value;
continue;
}
} else if (param.getParamType() == Parameter.ParamType.BATCH || param.getParamType() == Parameter.ParamType.RESOURCE_KEY) {
// should not come to this routine since it should be handled by passing in positionalArguments
throw new RoutingException("Parameter '" + param.getName() + "' should be passed in as a positional argument", HttpStatus.S_400_BAD_REQUEST.getCode());
} else {
// unknown param type
throw new RoutingException("Parameter '" + param.getName() + "' has an unknown parameter type '" + param.getParamType().name() + "'", HttpStatus.S_400_BAD_REQUEST.getCode());
}
} catch (TemplateRuntimeException e) {
throw new RoutingException("Parameter '" + param.getName() + "' is invalid", HttpStatus.S_400_BAD_REQUEST.getCode());
}
try {
// check if it is optional parameter
if (param.isOptional() && param.hasDefaultValue()) {
arguments[i] = param.getDefaultValue();
} else if (param.isOptional() && !param.getType().isPrimitive()) {
// optional primitive parameter must have default value or provided
arguments[i] = null;
} else {
throw new RoutingException("Parameter '" + param.getName() + "' is required", HttpStatus.S_400_BAD_REQUEST.getCode());
}
} catch (ResourceConfigException e) {
// Parameter default value format exception should result in server error code 500.
throw new RestLiServiceException(HttpStatus.S_500_INTERNAL_SERVER_ERROR, "Parameter '" + param.getName() + "' default value is invalid", e);
}
}
//that were not needed is safe, but not for request attachments.
if (!attachmentsDesired && ((ServerResourceContext) context).getRequestAttachmentReader() != null) {
throw new RestLiServiceException(HttpStatus.S_400_BAD_REQUEST, "Resource method endpoint invoked does not accept any request attachments.");
}
return arguments;
}
use of com.linkedin.restli.server.RestLiServiceException in project rest.li by linkedin.
the class RestLiResponseDataImpl method setException.
/**
* Sets the top level exception of this response.
* Each inheriting class must maintain invariant unique to its type.
*
* This method is for internal use only. If you wish to set an exception in a filter, please do so by either throwing
* an exception or by completing the future exceptionally. For more information see {@link com.linkedin.restli.server.filter.Filter}.
*
* @param throwable to set this response to.
*/
public void setException(Throwable throwable) {
if (throwable == null) {
throw new UnsupportedOperationException("Null is not permitted in setting an exception.");
}
RestLiServiceException restLiServiceException;
if (throwable instanceof RestLiServiceException) {
restLiServiceException = (RestLiServiceException) throwable;
} else if (throwable instanceof RoutingException) {
RoutingException routingException = (RoutingException) throwable;
restLiServiceException = new RestLiServiceException(HttpStatus.fromCode(routingException.getStatus()), routingException.getMessage(), routingException);
} else {
restLiServiceException = new RestLiServiceException(HttpStatus.S_500_INTERNAL_SERVER_ERROR, throwable.getMessage(), throwable);
}
setServiceException(restLiServiceException);
}
use of com.linkedin.restli.server.RestLiServiceException in project rest.li by linkedin.
the class ActionResponseBuilder method buildRestLiResponseData.
@Override
public RestLiResponseData buildRestLiResponseData(RestRequest request, RoutingResult routingResult, Object result, Map<String, String> headers, List<HttpCookie> cookies) {
final Object value;
final HttpStatus status;
if (result instanceof ActionResult) {
final ActionResult<?> actionResult = (ActionResult<?>) result;
value = actionResult.getValue();
status = actionResult.getStatus();
if (status == null) {
throw new RestLiServiceException(HttpStatus.S_500_INTERNAL_SERVER_ERROR, "Unexpected null encountered. Null HttpStatus inside of an ActionResult returned by the resource method: " + routingResult.getResourceMethod());
}
} else {
value = result;
status = HttpStatus.S_200_OK;
}
RecordDataSchema actionReturnRecordDataSchema = routingResult.getResourceMethod().getActionReturnRecordDataSchema();
@SuppressWarnings("unchecked") FieldDef<Object> actionReturnFieldDef = (FieldDef<Object>) routingResult.getResourceMethod().getActionReturnFieldDef();
final ActionResponse<?> actionResponse = new ActionResponse<Object>(value, actionReturnFieldDef, actionReturnRecordDataSchema);
RestLiResponseDataImpl responseData = new RestLiResponseDataImpl(status, headers, cookies);
responseData.setResponseEnvelope(new ActionResponseEnvelope(actionResponse, responseData));
return responseData;
}
use of com.linkedin.restli.server.RestLiServiceException in project rest.li by linkedin.
the class CreateResponseBuilder method buildRestLiResponseData.
@Override
public RestLiResponseData buildRestLiResponseData(RestRequest request, RoutingResult routingResult, Object result, Map<String, String> headers, List<HttpCookie> cookies) {
CreateResponse createResponse = (CreateResponse) result;
if (createResponse.hasError()) {
RestLiResponseDataImpl responseData = new RestLiResponseDataImpl(createResponse.getError(), headers, cookies);
responseData.setResponseEnvelope(new CreateResponseEnvelope(null, responseData));
return responseData;
}
Object id = null;
if (createResponse.hasId()) {
id = ResponseUtils.translateCanonicalKeyToAlternativeKeyIfNeeded(createResponse.getId(), routingResult);
final ProtocolVersion protocolVersion = ((ServerResourceContext) routingResult.getContext()).getRestliProtocolVersion();
String stringKey = URIParamUtils.encodeKeyForUri(id, UriComponent.Type.PATH_SEGMENT, protocolVersion);
UriBuilder uribuilder = UriBuilder.fromUri(request.getURI());
uribuilder.path(stringKey);
if (routingResult.getContext().hasParameter(RestConstants.ALT_KEY_PARAM)) {
// add altkey param to location URI
uribuilder.queryParam(RestConstants.ALT_KEY_PARAM, routingResult.getContext().getParameter(RestConstants.ALT_KEY_PARAM));
}
headers.put(RestConstants.HEADER_LOCATION, uribuilder.build((Object) null).toString());
headers.put(HeaderUtil.getIdHeaderName(protocolVersion), URIParamUtils.encodeKeyForHeader(id, protocolVersion));
}
//Verify that a null status was not passed into the CreateResponse. If so, this is a developer error.
if (createResponse.getStatus() == null) {
throw new RestLiServiceException(HttpStatus.S_500_INTERNAL_SERVER_ERROR, "Unexpected null encountered. HttpStatus is null inside of a CreateResponse from the resource method: " + routingResult.getResourceMethod());
}
RestLiResponseDataImpl responseData = new RestLiResponseDataImpl(createResponse.getStatus(), headers, cookies);
CreateResponseEnvelope responseEnvelope;
if (createResponse instanceof CreateKVResponse) {
final ResourceContext resourceContext = routingResult.getContext();
DataMap entityData = ((CreateKVResponse) createResponse).getEntity().data();
final DataMap data = RestUtils.projectFields(entityData, resourceContext.getProjectionMode(), resourceContext.getProjectionMask());
responseEnvelope = new CreateResponseEnvelope(new AnyRecord(data), true, responseData);
} else //Instance of idResponse
{
IdResponse<?> idResponse = new IdResponse<Object>(id);
responseEnvelope = new CreateResponseEnvelope(idResponse, responseData);
}
responseData.setResponseEnvelope(responseEnvelope);
return responseData;
}
Aggregations