Search in sources :

Example 1 with AlternativeKeyCoercerException

use of com.linkedin.restli.internal.server.util.AlternativeKeyCoercerException in project rest.li by linkedin.

the class ResponseUtils method translateCanonicalKeyToAlternativeKeyIfNeeded.

/**
   * If needed, translate a given canonical key to its alternative format.
   *
   * @param canonicalKey the canonical key
   * @param routingResult the routing result
   * @return the canonical key if the request did not use or ask for alternative keys, the alternative key otherwise.
   */
static Object translateCanonicalKeyToAlternativeKeyIfNeeded(Object canonicalKey, RoutingResult routingResult) {
    if (routingResult.getContext().hasParameter(RestConstants.ALT_KEY_PARAM)) {
        String altKeyName = routingResult.getContext().getParameter(RestConstants.ALT_KEY_PARAM);
        ResourceModel resourceModel = routingResult.getResourceMethod().getResourceModel();
        try {
            return ArgumentUtils.translateToAlternativeKey(canonicalKey, altKeyName, resourceModel);
        } catch (AlternativeKeyCoercerException e) {
            throw new RestLiServiceException(HttpStatus.S_500_INTERNAL_SERVER_ERROR, String.format("Unexpected Error when coercing canonical key '%s' to alternative key type '%s'", canonicalKey, altKeyName), e);
        }
    } else {
        return canonicalKey;
    }
}
Also used : RestLiServiceException(com.linkedin.restli.server.RestLiServiceException) AlternativeKeyCoercerException(com.linkedin.restli.internal.server.util.AlternativeKeyCoercerException) ResourceModel(com.linkedin.restli.internal.server.model.ResourceModel)

Example 2 with AlternativeKeyCoercerException

use of com.linkedin.restli.internal.server.util.AlternativeKeyCoercerException in project rest.li by linkedin.

the class ArgumentBuilder method parseEntityStringKey.

/**
   * Parses the provided string key value and returns its corresponding typed key instance. This method should only be
   * used to parse keys which appear in the request body.
   *
   * @param stringKey Key string from the entity body
   * @param routingResult {@link RoutingResult} instance for the current request
   * @param version {@link ProtocolVersion} instance of the current request
   * @return An instance of key's corresponding type
   */
static Object parseEntityStringKey(final String stringKey, final RoutingResult routingResult, final ProtocolVersion version) {
    ResourceModel resourceModel = routingResult.getResourceMethod().getResourceModel();
    ResourceContext resourceContext = routingResult.getContext();
    try {
        Key primaryKey = resourceModel.getPrimaryKey();
        String altKeyName = resourceContext.getParameter(RestConstants.ALT_KEY_PARAM);
        if (altKeyName != null) {
            return ArgumentUtils.translateFromAlternativeKey(ArgumentUtils.parseAlternativeKey(stringKey, altKeyName, resourceModel, version), altKeyName, resourceModel);
        } else if (ComplexResourceKey.class.equals(primaryKey.getType())) {
            return ComplexResourceKey.parseString(stringKey, resourceModel.getKeyKeyClass(), resourceModel.getKeyParamsClass(), version);
        } else if (CompoundKey.class.equals(primaryKey.getType())) {
            return ArgumentUtils.parseCompoundKey(stringKey, resourceModel.getKeys(), version);
        } else {
            // The conversion of simple keys doesn't include URL decoding as the current version of Rest.li clients don't
            // encode simple keys which appear in the request body for BATCH UPDATE and BATCH PATCH requests.
            Key key = resourceModel.getPrimaryKey();
            return ArgumentUtils.convertSimpleValue(stringKey, key.getDataSchema(), key.getType());
        }
    } catch (InvalidAlternativeKeyException | AlternativeKeyCoercerException | PathSegment.PathSegmentSyntaxException | IllegalArgumentException e) {
        throw new RoutingException(String.format("Invalid key: '%s'", stringKey), HttpStatus.S_400_BAD_REQUEST.getCode());
    }
}
Also used : RoutingException(com.linkedin.restli.server.RoutingException) ResourceContext(com.linkedin.restli.server.ResourceContext) ServerResourceContext(com.linkedin.restli.internal.server.ServerResourceContext) InvalidAlternativeKeyException(com.linkedin.data.template.InvalidAlternativeKeyException) AlternativeKeyCoercerException(com.linkedin.restli.internal.server.util.AlternativeKeyCoercerException) ComplexResourceKey(com.linkedin.restli.common.ComplexResourceKey) ResourceModel(com.linkedin.restli.internal.server.model.ResourceModel) ComplexResourceKey(com.linkedin.restli.common.ComplexResourceKey) Key(com.linkedin.restli.server.Key) CompoundKey(com.linkedin.restli.common.CompoundKey)

Example 3 with AlternativeKeyCoercerException

use of com.linkedin.restli.internal.server.util.AlternativeKeyCoercerException 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;
}
Also used : RoutingException(com.linkedin.restli.server.RoutingException) InvalidAlternativeKeyException(com.linkedin.data.template.InvalidAlternativeKeyException) RestLiServiceException(com.linkedin.restli.server.RestLiServiceException) AlternativeKeyCoercerException(com.linkedin.restli.internal.server.util.AlternativeKeyCoercerException) HashSet(java.util.HashSet)

Example 4 with AlternativeKeyCoercerException

use of com.linkedin.restli.internal.server.util.AlternativeKeyCoercerException 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);
    }
}
Also used : RoutingException(com.linkedin.restli.server.RoutingException) InvalidAlternativeKeyException(com.linkedin.data.template.InvalidAlternativeKeyException) AlternativeKeyCoercerException(com.linkedin.restli.internal.server.util.AlternativeKeyCoercerException)

Aggregations

AlternativeKeyCoercerException (com.linkedin.restli.internal.server.util.AlternativeKeyCoercerException)4 InvalidAlternativeKeyException (com.linkedin.data.template.InvalidAlternativeKeyException)3 RoutingException (com.linkedin.restli.server.RoutingException)3 ResourceModel (com.linkedin.restli.internal.server.model.ResourceModel)2 RestLiServiceException (com.linkedin.restli.server.RestLiServiceException)2 ComplexResourceKey (com.linkedin.restli.common.ComplexResourceKey)1 CompoundKey (com.linkedin.restli.common.CompoundKey)1 ServerResourceContext (com.linkedin.restli.internal.server.ServerResourceContext)1 Key (com.linkedin.restli.server.Key)1 ResourceContext (com.linkedin.restli.server.ResourceContext)1 HashSet (java.util.HashSet)1