Search in sources :

Example 1 with TemplateRuntimeException

use of com.linkedin.data.template.TemplateRuntimeException 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;
}
Also used : RoutingException(com.linkedin.restli.server.RoutingException) PathSegmentSyntaxException(com.linkedin.restli.internal.common.PathSegment.PathSegmentSyntaxException) CompoundKey(com.linkedin.restli.common.CompoundKey) TemplateRuntimeException(com.linkedin.data.template.TemplateRuntimeException)

Example 2 with TemplateRuntimeException

use of com.linkedin.data.template.TemplateRuntimeException 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);
}
Also used : RoutingException(com.linkedin.restli.server.RoutingException) CompoundKey(com.linkedin.restli.common.CompoundKey) ProtocolVersion(com.linkedin.restli.common.ProtocolVersion) DataMap(com.linkedin.data.DataMap) DataList(com.linkedin.data.DataList) PathSegmentSyntaxException(com.linkedin.restli.internal.common.PathSegment.PathSegmentSyntaxException) RestLiServiceException(com.linkedin.restli.server.RestLiServiceException) ComplexResourceKey(com.linkedin.restli.common.ComplexResourceKey) TemplateRuntimeException(com.linkedin.data.template.TemplateRuntimeException) LinkedList(java.util.LinkedList) DataList(com.linkedin.data.DataList) List(java.util.List) ComplexResourceKey(com.linkedin.restli.common.ComplexResourceKey) Key(com.linkedin.restli.server.Key) CompoundKey(com.linkedin.restli.common.CompoundKey) HashSet(java.util.HashSet)

Example 3 with TemplateRuntimeException

use of com.linkedin.data.template.TemplateRuntimeException in project rest.li by linkedin.

the class RestLiAnnotationReader method buildActionParam.

@SuppressWarnings({ "unchecked", "rawtypes" })
private static Parameter buildActionParam(final Method method, final AnnotationSet annotations, final Class<?> paramType) {
    ActionParam actionParam = annotations.get(ActionParam.class);
    Optional optional = annotations.get(Optional.class);
    String paramName = actionParam.value();
    Class<? extends TyperefInfo> typerefInfoClass = actionParam.typeref();
    try {
        Parameter param = new Parameter(paramName, paramType, getDataSchema(paramType, getSchemaFromTyperefInfo(typerefInfoClass)), optional != null, getDefaultValueData(optional), Parameter.ParamType.POST, true, annotations);
        return param;
    } catch (TemplateRuntimeException e) {
        throw new ResourceConfigException("DataSchema for parameter '" + paramName + "' of type " + paramType.getSimpleName() + " on " + buildMethodMessage(method) + "cannot be found; type is invalid or requires typeref", e);
    } catch (Exception e) {
        throw new ResourceConfigException("Typeref for parameter '" + paramName + "' on " + buildMethodMessage(method) + " cannot be instantiated, " + e.getMessage(), e);
    }
}
Also used : ActionParam(com.linkedin.restli.server.annotations.ActionParam) Optional(com.linkedin.restli.server.annotations.Optional) TemplateRuntimeException(com.linkedin.data.template.TemplateRuntimeException) ResourceConfigException(com.linkedin.restli.server.ResourceConfigException) TemplateRuntimeException(com.linkedin.data.template.TemplateRuntimeException) ResourceConfigException(com.linkedin.restli.server.ResourceConfigException) RestLiInternalException(com.linkedin.restli.internal.server.RestLiInternalException)

Example 4 with TemplateRuntimeException

use of com.linkedin.data.template.TemplateRuntimeException in project rest.li by linkedin.

the class RestLiAnnotationReader method checkTyperefSchema.

private static String checkTyperefSchema(final Class<?> type, final DataSchema dataSchema) {
    if (type.isArray() && dataSchema instanceof ArrayDataSchema) {
        registerCoercerForPrimitiveTypeRefArray((ArrayDataSchema) dataSchema);
    }
    if (!(dataSchema instanceof TyperefDataSchema)) {
        return null;
    }
    TyperefDataSchema typerefSchema = (TyperefDataSchema) dataSchema;
    boolean ok;
    DataSchema.Type schemaType = typerefSchema.getDereferencedType();
    Class<?>[] validTypes = RestModelConstants.PRIMITIVE_DATA_SCHEMA_TYPE_ALLOWED_TYPES.get(schemaType);
    if (validTypes != null) {
        String javaClassNameFromSchema = CustomTypeUtil.getJavaCustomTypeClassNameFromSchema(typerefSchema);
        if (javaClassNameFromSchema != null) {
            registerCoercer(typerefSchema);
            ok = type.getName().equals(javaClassNameFromSchema) || (type.isArray() && (type.getComponentType().getName()).equals(javaClassNameFromSchema));
        } else {
            ok = checkParameterType(type, validTypes);
        }
    } else {
        try {
            DataSchema inferredSchema = DataTemplateUtil.getSchema(type);
            DataSchema derefSchema = typerefSchema.getDereferencedDataSchema();
            if (inferredSchema.equals(derefSchema)) {
                return null;
            }
            return "typeref " + typerefSchema + " is not compatible with (" + type + ") with schema " + derefSchema;
        } catch (TemplateRuntimeException e) {
        }
        ok = false;
    }
    if (!ok) {
        return "typeref " + typerefSchema + " is not compatible with (" + type + ")";
    }
    return null;
}
Also used : TyperefDataSchema(com.linkedin.data.schema.TyperefDataSchema) ArrayDataSchema(com.linkedin.data.schema.ArrayDataSchema) DataSchema(com.linkedin.data.schema.DataSchema) RecordDataSchema(com.linkedin.data.schema.RecordDataSchema) ArrayDataSchema(com.linkedin.data.schema.ArrayDataSchema) TyperefDataSchema(com.linkedin.data.schema.TyperefDataSchema) TemplateRuntimeException(com.linkedin.data.template.TemplateRuntimeException)

Example 5 with TemplateRuntimeException

use of com.linkedin.data.template.TemplateRuntimeException in project rest.li by linkedin.

the class RestLiAnnotationReader method buildAssocKeyParam.

private static Parameter<?> buildAssocKeyParam(final ResourceModel model, final Method method, final AnnotationSet annotations, final Class<?> paramType, final Class<?> paramAnnotationType) {
    Parameter.ParamType parameter = null;
    String assocKeyParamValue = null;
    Class<? extends TyperefInfo> typerefInfoClass = null;
    if (paramAnnotationType.equals(AssocKey.class)) {
        parameter = Parameter.ParamType.KEY;
        assocKeyParamValue = annotations.get(AssocKey.class).value();
        typerefInfoClass = annotations.get(AssocKey.class).typeref();
    } else if (paramAnnotationType.equals(AssocKeyParam.class)) {
        parameter = Parameter.ParamType.ASSOC_KEY_PARAM;
        assocKeyParamValue = annotations.get(AssocKeyParam.class).value();
        typerefInfoClass = annotations.get(AssocKeyParam.class).typeref();
    } else {
        throw new ResourceConfigException("Param Annotation type must be 'AssocKeysParam' or the deprecated 'AssocKey' for AssocKey");
    }
    Optional optional = annotations.get(Optional.class);
    if (!checkAssocKey(model.getKeys(), assocKeyParamValue)) {
        throw new ResourceConfigException("Non-existing assocKey '" + assocKeyParamValue + "' on " + buildMethodMessage(method));
    }
    try {
        @SuppressWarnings({ "unchecked", "rawtypes" }) Parameter<?> param = new Parameter(assocKeyParamValue, paramType, getDataSchema(paramType, getSchemaFromTyperefInfo(typerefInfoClass)), optional != null, getDefaultValueData(optional), parameter, true, annotations);
        return param;
    } catch (TemplateRuntimeException e) {
        throw new ResourceConfigException("DataSchema for assocKey '" + assocKeyParamValue + "' of type " + paramType.getSimpleName() + " on " + buildMethodMessage(method) + "cannot be found; type is invalid or requires typeref", e);
    } catch (Exception e) {
        throw new ResourceConfigException("Typeref for assocKey '" + assocKeyParamValue + "' on " + buildMethodMessage(method) + " cannot be instantiated, " + e.getMessage(), e);
    }
}
Also used : Optional(com.linkedin.restli.server.annotations.Optional) TemplateRuntimeException(com.linkedin.data.template.TemplateRuntimeException) AssocKeyParam(com.linkedin.restli.server.annotations.AssocKeyParam) ResourceConfigException(com.linkedin.restli.server.ResourceConfigException) TemplateRuntimeException(com.linkedin.data.template.TemplateRuntimeException) ResourceConfigException(com.linkedin.restli.server.ResourceConfigException) RestLiInternalException(com.linkedin.restli.internal.server.RestLiInternalException)

Aggregations

TemplateRuntimeException (com.linkedin.data.template.TemplateRuntimeException)12 RoutingException (com.linkedin.restli.server.RoutingException)6 ResourceConfigException (com.linkedin.restli.server.ResourceConfigException)5 RestLiInternalException (com.linkedin.restli.internal.server.RestLiInternalException)4 ArrayDataSchema (com.linkedin.data.schema.ArrayDataSchema)3 Optional (com.linkedin.restli.server.annotations.Optional)3 DataList (com.linkedin.data.DataList)2 DataMap (com.linkedin.data.DataMap)2 DataSchema (com.linkedin.data.schema.DataSchema)2 RecordDataSchema (com.linkedin.data.schema.RecordDataSchema)2 TyperefDataSchema (com.linkedin.data.schema.TyperefDataSchema)2 ValidationOptions (com.linkedin.data.schema.validation.ValidationOptions)2 CompoundKey (com.linkedin.restli.common.CompoundKey)2 PathSegmentSyntaxException (com.linkedin.restli.internal.common.PathSegment.PathSegmentSyntaxException)2 RestLiServiceException (com.linkedin.restli.server.RestLiServiceException)2 MapDataSchema (com.linkedin.data.schema.MapDataSchema)1 UnionDataSchema (com.linkedin.data.schema.UnionDataSchema)1 DataSchemaAnnotationValidator (com.linkedin.data.schema.validator.DataSchemaAnnotationValidator)1 DataTemplate (com.linkedin.data.template.DataTemplate)1 ComplexResourceKey (com.linkedin.restli.common.ComplexResourceKey)1