use of com.linkedin.restli.server.RoutingException in project rest.li by linkedin.
the class RestLiRouter method parseCompoundKey.
private static CompoundKey parseCompoundKey(final ResourceModel resource, final ServerResourceContext context, final String pathSegment) {
CompoundKey compoundKey;
try {
compoundKey = ArgumentUtils.parseCompoundKey(pathSegment, resource.getKeys(), context.getRestliProtocolVersion());
} catch (PathSegmentSyntaxException e) {
throw new RoutingException(String.format("input %s is not a Compound key", pathSegment), HttpStatus.S_400_BAD_REQUEST.getCode(), e);
} catch (IllegalArgumentException e) {
throw new RoutingException(String.format("input %s is not a Compound key", pathSegment), HttpStatus.S_400_BAD_REQUEST.getCode(), e);
} catch (TemplateRuntimeException e) {
// thrown from DateTemplateUtil.coerceOutput
throw new RoutingException(String.format("Compound key parameter value %s is invalid", pathSegment), HttpStatus.S_400_BAD_REQUEST.getCode(), e);
}
for (String simpleKeyName : compoundKey.getPartKeys()) {
context.getPathKeys().append(simpleKeyName, compoundKey.getPart(simpleKeyName));
}
context.getPathKeys().append(resource.getKeyName(), compoundKey);
return compoundKey;
}
use of com.linkedin.restli.server.RoutingException in project rest.li by linkedin.
the class RestLiRouter method parseBatchKeysParameter.
private void parseBatchKeysParameter(final ResourceModel resource, final ServerResourceContext context) {
Class<?> keyClass = resource.getKeyClass();
ProtocolVersion version = context.getRestliProtocolVersion();
final Set<Object> batchKeys;
try {
if (context.getParameters().containsKey(RestConstants.ALT_KEY_PARAM)) {
batchKeys = parseAlternativeBatchKeys(resource, context);
} else if (ComplexResourceKey.class.equals(keyClass)) {
// Parse all query parameters into a data map.
DataMap allParametersDataMap = context.getParameters();
// Get the batch request keys from the IDS list at the root of the map.
DataList batchIds = allParametersDataMap.getDataList(RestConstants.QUERY_BATCH_IDS_PARAM);
if (batchIds == null) {
batchKeys = null;
} else if (batchIds.isEmpty()) {
batchKeys = Collections.emptySet();
} else {
batchKeys = new HashSet<Object>();
// Validate the complex keys and put them into the context batch keys
for (Object complexKey : batchIds) {
if (!(complexKey instanceof DataMap)) {
log.warn("Invalid structure of key '" + complexKey.toString() + "', skipping key.");
context.getBatchKeyErrors().put(complexKey, new RestLiServiceException(HttpStatus.S_400_BAD_REQUEST));
continue;
}
batchKeys.add(ComplexResourceKey.buildFromDataMap((DataMap) complexKey, ComplexKeySpec.forClassesMaybeNull(resource.getKeyKeyClass(), resource.getKeyParamsClass())));
}
}
} else if (CompoundKey.class.equals(keyClass) && version.compareTo(AllProtocolVersions.RESTLI_PROTOCOL_2_0_0.getProtocolVersion()) >= 0) {
DataMap allParametersDataMap = context.getParameters();
// Get the batch request keys from the IDS list at the root of the map.
DataList batchIds = allParametersDataMap.getDataList(RestConstants.QUERY_BATCH_IDS_PARAM);
if (batchIds == null) {
batchKeys = null;
} else if (batchIds.isEmpty()) {
batchKeys = Collections.emptySet();
} else {
batchKeys = new HashSet<Object>();
// Validate the compound keys and put them into the contex batch keys
for (Object compoundKey : batchIds) {
if (!(compoundKey instanceof DataMap)) {
log.warn("Invalid structure of key '" + compoundKey.toString() + "', skipping key.");
context.getBatchKeyErrors().put(compoundKey.toString(), new RestLiServiceException(HttpStatus.S_400_BAD_REQUEST));
continue;
}
CompoundKey finalKey;
try {
finalKey = ArgumentUtils.dataMapToCompoundKey((DataMap) compoundKey, resource.getKeys());
} catch (IllegalArgumentException e) {
log.warn("Invalid structure of key '" + compoundKey.toString() + "', skipping key.");
context.getBatchKeyErrors().put(compoundKey.toString(), new RestLiServiceException(HttpStatus.S_400_BAD_REQUEST));
continue;
}
batchKeys.add(finalKey);
}
}
} else // collection batch get in v2, collection or association batch get in v1
if (context.hasParameter(RestConstants.QUERY_BATCH_IDS_PARAM)) {
batchKeys = new HashSet<Object>();
List<String> ids = context.getParameterValues(RestConstants.QUERY_BATCH_IDS_PARAM);
if (version.compareTo(AllProtocolVersions.RESTLI_PROTOCOL_2_0_0.getProtocolVersion()) >= 0) {
for (String id : ids) {
Key key = resource.getPrimaryKey();
Object value;
try {
// in v2, compound keys have already been converted and dealt with, so all we need to do here is convert simple values.
value = ArgumentUtils.convertSimpleValue(id, key.getDataSchema(), key.getType());
batchKeys.add(value);
} catch (NumberFormatException e) {
throw new RoutingException("NumberFormatException parsing batch key '" + id + "'", HttpStatus.S_400_BAD_REQUEST.getCode(), e);
} catch (IllegalArgumentException e) {
throw new RoutingException("IllegalArgumentException parsing batch key '" + id + "'", HttpStatus.S_400_BAD_REQUEST.getCode(), e);
}
}
} else {
for (String id : ids) {
try {
// in v1, compound keys have not been fully parsed or dealt with yet, so we need to take them into account.
Object value = parseKeyFromBatchV1(id, resource);
batchKeys.add(value);
} catch (NumberFormatException e) {
log.warn("Caught NumberFormatException parsing batch key '" + id + "', skipping key.");
context.getBatchKeyErrors().put(id, new RestLiServiceException(HttpStatus.S_400_BAD_REQUEST, null, e));
} catch (IllegalArgumentException e) {
log.warn("Caught IllegalArgumentException parsing batch key '" + id + "', skipping key.");
context.getBatchKeyErrors().put(id, new RestLiServiceException(HttpStatus.S_400_BAD_REQUEST, null, e));
} catch (PathSegmentSyntaxException e) {
log.warn("Caught IllegalArgumentException parsing batch key '" + id + "', skipping key.");
context.getBatchKeyErrors().put(id, new RestLiServiceException(HttpStatus.S_400_BAD_REQUEST, null, e));
}
}
}
} else {
batchKeys = null;
}
} catch (TemplateRuntimeException e) {
// thrown from DateTemplateUtil.coerceOutput
throw new RoutingException("Batch key parameter value is invalid", HttpStatus.S_400_BAD_REQUEST.getCode(), e);
}
context.getPathKeys().setBatchKeys(batchKeys);
}
use of com.linkedin.restli.server.RoutingException in project rest.li by linkedin.
the class RestLiRouter method parseAlternativeBatchKeys.
private static Set<Object> parseAlternativeBatchKeys(final ResourceModel resource, final ServerResourceContext context) {
String altKeyName = context.getParameter(RestConstants.ALT_KEY_PARAM);
List<String> ids = context.getParameterValues(RestConstants.QUERY_BATCH_IDS_PARAM);
Set<Object> batchKeys = new HashSet<Object>();
if (ids == null) {
batchKeys = null;
} else if (ids.isEmpty()) {
batchKeys = Collections.emptySet();
} else {
if (!resource.getAlternativeKeys().containsKey(altKeyName)) {
throw new RoutingException(String.format("Resource '%s' does not have an alternative key named '%s'", resource.getName(), altKeyName), HttpStatus.S_400_BAD_REQUEST.getCode());
}
for (String id : ids) {
try {
batchKeys.add(ArgumentUtils.translateFromAlternativeKey(ArgumentUtils.parseAlternativeKey(id, altKeyName, resource, context.getRestliProtocolVersion()), altKeyName, resource));
} catch (InvalidAlternativeKeyException e) {
log.warn(String.format("Invalid alternative key '%s', skipping key.", id));
context.getBatchKeyErrors().put(id, new RestLiServiceException(HttpStatus.S_400_BAD_REQUEST, e));
} catch (AlternativeKeyCoercerException e) {
throw new RoutingException(String.format("Unexpected error when coercing alternative key '%s': %s", id, e.getMessage()), HttpStatus.S_500_INTERNAL_SERVER_ERROR.getCode());
}
}
}
return batchKeys;
}
use of com.linkedin.restli.server.RoutingException in project rest.li by linkedin.
the class ArgumentBuilder method buildRegularArgument.
/**
* Build a method argument from a request parameter that is NOT backed by a schema, i.e.
* a primitive or an array
*
* @param context {@link ResourceContext}
* @param param {@link Parameter}
* @return argument value in the correct type
*/
private static Object buildRegularArgument(final ResourceContext context, final Parameter<?> param) {
String value = ArgumentUtils.argumentAsString(context.getParameter(param.getName()), param.getName());
final Object convertedValue;
if (value == null) {
return null;
} else {
if (param.isArray()) {
convertedValue = buildArrayArgument(context, param);
} else {
try {
convertedValue = ArgumentUtils.convertSimpleValue(value, param.getDataSchema(), param.getType());
} catch (NumberFormatException e) {
Class<?> targetClass = DataSchemaUtil.dataSchemaTypeToPrimitiveDataSchemaClass(param.getDataSchema().getDereferencedType());
// thrown from Integer.valueOf or Long.valueOf
throw new RoutingException(String.format("Argument parameter '%s' value '%s' must be of type '%s'", param.getName(), value, targetClass.getName()), HttpStatus.S_400_BAD_REQUEST.getCode());
} catch (IllegalArgumentException e) {
// thrown from Enum.valueOf
throw new RoutingException(String.format("Argument parameter '%s' value '%s' is invalid", param.getName(), value), HttpStatus.S_400_BAD_REQUEST.getCode());
} catch (TemplateRuntimeException e) {
// thrown from DataTemplateUtil.coerceOutput
throw new RoutingException(String.format("Argument parameter '%s' value '%s' is invalid. Reason: %s", param.getName(), value, e.getMessage()), HttpStatus.S_400_BAD_REQUEST.getCode());
}
}
}
return convertedValue;
}
use of com.linkedin.restli.server.RoutingException in project rest.li by linkedin.
the class RestLiRouter method parseAlternativeKey.
/**
* Coercers the alternative key into a primary key and puts it into path keys.
*
* @param resource the {@link com.linkedin.restli.internal.server.model.ResourceModel} of the resource.
* @param context the {@link com.linkedin.restli.internal.server.ServerResourceContext} of the request.
* @param currentPathSegment the serialized alternative key.
*/
private static <K> void parseAlternativeKey(final ResourceModel resource, final ServerResourceContext context, final String currentPathSegment) {
String altKeyName = context.getParameter(RestConstants.ALT_KEY_PARAM);
Object alternativeKey;
try {
alternativeKey = ArgumentUtils.parseAlternativeKey(currentPathSegment, context.getParameter(RestConstants.ALT_KEY_PARAM), resource, context.getRestliProtocolVersion());
} catch (IllegalArgumentException e) {
throw new RoutingException(e.getMessage(), HttpStatus.S_400_BAD_REQUEST.getCode());
}
try {
K canonicalKey = ArgumentUtils.translateFromAlternativeKey(alternativeKey, altKeyName, resource);
context.getPathKeys().append(resource.getKeyName(), canonicalKey);
} catch (InvalidAlternativeKeyException e) {
throw new RoutingException(e.getMessage(), HttpStatus.S_400_BAD_REQUEST.getCode());
} catch (AlternativeKeyCoercerException e) {
throw new RoutingException("KeyCoercer threw an unexpected exception", HttpStatus.S_500_INTERNAL_SERVER_ERROR.getCode(), e);
}
}
Aggregations