Search in sources :

Example 41 with ResourceModel

use of com.linkedin.restli.internal.server.model.ResourceModel in project rest.li by linkedin.

the class TestPhotoResource method buildResourceModels.

private static Map<String, ResourceModel> buildResourceModels(Class<?>... rootResourceClasses) {
    final Map<String, ResourceModel> map = new HashMap<>();
    for (Class<?> rootResourceClass : rootResourceClasses) {
        final ResourceModel model = RestLiAnnotationReader.processResource(rootResourceClass);
        map.put("/" + model.getName(), model);
    }
    return map;
}
Also used : HashMap(java.util.HashMap) ResourceModel(com.linkedin.restli.internal.server.model.ResourceModel)

Example 42 with ResourceModel

use of com.linkedin.restli.internal.server.model.ResourceModel in project rest.li by linkedin.

the class TestExamplesGenerator method testExamples.

@Test
public void testExamples() throws IOException {
    final Map<String, ResourceModel> resources = buildResourceModels(ActionsResource.class, GreetingsResource.class, GroupsResource2.class, GroupContactsResource2.class, GroupMembershipsResource2.class, RootSimpleResource.class, CollectionUnderSimpleResource.class, SimpleResourceUnderCollectionResource.class, CustomTypesResource.class);
    final ResourceSchemaCollection resourceSchemas = ResourceSchemaCollection.loadOrCreateResourceSchema(resources);
    final DataSchemaResolver schemaResolver = new ClasspathResourceDataSchemaResolver();
    final ValidationOptions valOptions = new ValidationOptions(RequiredMode.MUST_BE_PRESENT);
    ExampleRequestResponse capture;
    ValidationResult valRet;
    final ResourceSchema greetings = resourceSchemas.getResource("greetings");
    ExampleRequestResponseGenerator greetingsGenerator = new ExampleRequestResponseGenerator(greetings, schemaResolver);
    final ResourceSchema groups = resourceSchemas.getResource("groups");
    ExampleRequestResponseGenerator groupsGenerator = new ExampleRequestResponseGenerator(groups, schemaResolver);
    final ResourceSchema groupsContacts = resourceSchemas.getResource("groups.contacts");
    ExampleRequestResponseGenerator groupsContactsGenerator = new ExampleRequestResponseGenerator(Collections.singletonList(groups), groupsContacts, schemaResolver);
    final ResourceSchema greeting = resourceSchemas.getResource("greeting");
    ExampleRequestResponseGenerator greetingGenerator = new ExampleRequestResponseGenerator(greeting, schemaResolver);
    final ResourceSchema actions = resourceSchemas.getResource("actions");
    ExampleRequestResponseGenerator actionsGenerator = new ExampleRequestResponseGenerator(actions, schemaResolver);
    final ResourceSchema customTypes = resourceSchemas.getResource("customTypes");
    ExampleRequestResponseGenerator customTypesGenerator = new ExampleRequestResponseGenerator(customTypes, schemaResolver);
    List<ResourceSchema> subResources = resourceSchemas.getSubResources(greeting);
    final ResourceSchema subgreetings = subResources.get(0);
    ExampleRequestResponseGenerator subgreetingsGenerator = new ExampleRequestResponseGenerator(Collections.singletonList(greeting), subgreetings, schemaResolver);
    subResources = resourceSchemas.getSubResources(subgreetings);
    final ResourceSchema subsubgreeting = subResources.get(0);
    ExampleRequestResponseGenerator subsubgreetingGenerator = new ExampleRequestResponseGenerator(Arrays.asList(greeting, subgreetings), subsubgreeting, schemaResolver);
    capture = greetingsGenerator.method(ResourceMethod.GET);
    valRet = validateSingleResponse(capture.getResponse(), Greeting.class, valOptions);
    Assert.assertTrue(valRet.isValid(), valRet.getMessages().toString());
    capture = greetingsGenerator.method(ResourceMethod.CREATE);
    Assert.assertSame(capture.getResponse().getEntity().length(), 0);
    capture = greetingsGenerator.finder("search");
    valRet = validateCollectionResponse(capture.getResponse(), Greeting.class, valOptions);
    Assert.assertNull(valRet, (valRet == null ? null : valRet.getMessages().toString()));
    capture = groupsContactsGenerator.method(ResourceMethod.GET);
    valRet = validateSingleResponse(capture.getResponse(), GroupContact.class, valOptions);
    Assert.assertTrue(valRet.isValid(), valRet.getMessages().toString());
    capture = groupsGenerator.finder("search");
    String queryString = capture.getRequest().getURI().getQuery();
    Assert.assertTrue(queryString.contains("q=search"));
    Assert.assertTrue(queryString.contains("keywords="));
    Assert.assertTrue(queryString.contains("nameKeywords="));
    Assert.assertTrue(queryString.contains("groupID="));
    valRet = validateCollectionResponse(capture.getResponse(), Group.class, valOptions);
    Assert.assertNull(valRet, (valRet == null ? null : valRet.getMessages().toString()));
    capture = greetingsGenerator.action("purge", ResourceLevel.COLLECTION);
    final DataMap purgeResponse = DataMapUtils.readMap(capture.getResponse());
    Assert.assertTrue(purgeResponse.containsKey("value"));
    capture = greetingsGenerator.action("updateTone", ResourceLevel.ENTITY);
    valRet = validateCollectionResponse(capture.getResponse(), Greeting.class, valOptions);
    Assert.assertNull(valRet, (valRet == null ? null : valRet.getMessages().toString()));
    capture = groupsGenerator.action("sendTestAnnouncement", ResourceLevel.ENTITY);
    Assert.assertSame(capture.getResponse().getEntity().length(), 0);
    capture = greetingGenerator.method(ResourceMethod.GET);
    valRet = validateSingleResponse(capture.getResponse(), Greeting.class, valOptions);
    Assert.assertTrue(valRet.isValid(), valRet.getMessages().toString());
    RestRequest request = capture.getRequest();
    Assert.assertEquals(request.getURI(), URI.create("/greeting"));
    capture = greetingGenerator.method(ResourceMethod.UPDATE);
    Assert.assertSame(capture.getResponse().getEntity().length(), 0);
    request = capture.getRequest();
    Assert.assertEquals(request.getURI(), URI.create("/greeting"));
    valRet = validateSingleRequest(capture.getRequest(), Greeting.class, valOptions);
    Assert.assertTrue(valRet.isValid(), valRet.getMessages().toString());
    capture = greetingGenerator.method(ResourceMethod.PARTIAL_UPDATE);
    Assert.assertSame(capture.getResponse().getEntity().length(), 0);
    request = capture.getRequest();
    Assert.assertEquals(request.getURI(), URI.create("/greeting"));
    DataMap patchMap = _codec.bytesToMap(capture.getRequest().getEntity().copyBytes());
    checkPatchMap(patchMap);
    capture = greetingGenerator.method(ResourceMethod.DELETE);
    Assert.assertSame(capture.getResponse().getEntity().length(), 0);
    request = capture.getRequest();
    Assert.assertEquals(request.getURI(), URI.create("/greeting"));
    capture = greetingGenerator.action("exampleAction", ResourceLevel.ENTITY);
    DataMap exampleActionResponse = DataMapUtils.readMap(capture.getResponse());
    Assert.assertTrue(exampleActionResponse.containsKey("value"));
    request = capture.getRequest();
    Assert.assertTrue(validateUrlPath(request.getURI(), new String[] { "greeting" }));
    capture = subgreetingsGenerator.method(ResourceMethod.CREATE);
    Assert.assertSame(capture.getResponse().getEntity().length(), 0);
    request = capture.getRequest();
    Assert.assertEquals(request.getURI(), URI.create("/greeting/subgreetings"));
    valRet = validateSingleRequest(capture.getRequest(), Greeting.class, valOptions);
    Assert.assertTrue(valRet.isValid(), valRet.getMessages().toString());
    capture = subsubgreetingGenerator.method(ResourceMethod.GET);
    valRet = validateSingleResponse(capture.getResponse(), Greeting.class, valOptions);
    Assert.assertTrue(valRet.isValid(), valRet.getMessages().toString());
    request = capture.getRequest();
    Assert.assertTrue(validateUrlPath(request.getURI(), new String[] { "greeting", "subgreetings", null, "subsubgreeting" }));
    capture = subsubgreetingGenerator.method(ResourceMethod.UPDATE);
    Assert.assertSame(capture.getResponse().getEntity().length(), 0);
    request = capture.getRequest();
    Assert.assertTrue(validateUrlPath(request.getURI(), new String[] { "greeting", "subgreetings", null, "subsubgreeting" }));
    valRet = validateSingleRequest(capture.getRequest(), Greeting.class, valOptions);
    Assert.assertTrue(valRet.isValid(), valRet.getMessages().toString());
    capture = subsubgreetingGenerator.method(ResourceMethod.PARTIAL_UPDATE);
    Assert.assertSame(capture.getResponse().getEntity().length(), 0);
    request = capture.getRequest();
    Assert.assertTrue(validateUrlPath(request.getURI(), new String[] { "greeting", "subgreetings", null, "subsubgreeting" }));
    patchMap = _codec.bytesToMap(capture.getRequest().getEntity().copyBytes());
    checkPatchMap(patchMap);
    capture = subsubgreetingGenerator.method(ResourceMethod.DELETE);
    Assert.assertSame(capture.getResponse().getEntity().length(), 0);
    request = capture.getRequest();
    Assert.assertTrue(validateUrlPath(request.getURI(), new String[] { "greeting", "subgreetings", null, "subsubgreeting" }));
    capture = subsubgreetingGenerator.action("exampleAction", ResourceLevel.ENTITY);
    exampleActionResponse = DataMapUtils.readMap(capture.getResponse());
    Assert.assertTrue(exampleActionResponse.containsKey("value"));
    request = capture.getRequest();
    Assert.assertTrue(validateUrlPath(request.getURI(), new String[] { "greeting", "subgreetings", null, "subsubgreeting" }));
    capture = subgreetingsGenerator.finder("search");
    queryString = capture.getRequest().getURI().getQuery();
    Assert.assertTrue(queryString.contains("q=search"), queryString);
    Assert.assertTrue(queryString.contains("id:"), queryString);
    Assert.assertTrue(queryString.contains("message:"), queryString);
    Assert.assertTrue(queryString.contains("tone:"), queryString);
    capture = actionsGenerator.action("echoMessageArray", ResourceLevel.COLLECTION);
    final DataMap echoMessageArrayResponse = DataMapUtils.readMap(capture.getResponse());
    Assert.assertTrue(echoMessageArrayResponse.containsKey("value"));
    capture = actionsGenerator.action("echoToneArray", ResourceLevel.COLLECTION);
    final DataMap echoToneArrayResponse = DataMapUtils.readMap(capture.getResponse());
    Assert.assertTrue(echoToneArrayResponse.containsKey("value"));
    capture = actionsGenerator.action("echoStringArray", ResourceLevel.COLLECTION);
    final DataMap echoStringArrayResponse = DataMapUtils.readMap(capture.getResponse());
    Assert.assertTrue(echoStringArrayResponse.containsKey("value"));
    capture = customTypesGenerator.action("action", ResourceLevel.COLLECTION);
    DataMap requestMap = _codec.bytesToMap(capture.getRequest().getEntity().copyBytes());
    Assert.assertTrue(requestMap.containsKey("l"));
    Assert.assertEquals(requestMap.size(), 1);
    final DataMap customTypesActionResponse = DataMapUtils.readMap(capture.getResponse());
    Assert.assertTrue(customTypesActionResponse.containsKey("value"));
    Assert.assertEquals(customTypesActionResponse.size(), 1);
}
Also used : Greeting(com.linkedin.restli.examples.greetings.api.Greeting) Group(com.linkedin.restli.examples.groups.api.Group) ResourceSchema(com.linkedin.restli.restspec.ResourceSchema) ExampleRequestResponse(com.linkedin.restli.docgen.examplegen.ExampleRequestResponse) ByteString(com.linkedin.data.ByteString) ValidationOptions(com.linkedin.data.schema.validation.ValidationOptions) ValidationResult(com.linkedin.data.schema.validation.ValidationResult) GroupContact(com.linkedin.restli.examples.groups.api.GroupContact) DataMap(com.linkedin.data.DataMap) ExampleRequestResponseGenerator(com.linkedin.restli.docgen.examplegen.ExampleRequestResponseGenerator) RestRequest(com.linkedin.r2.message.rest.RestRequest) ClasspathResourceDataSchemaResolver(com.linkedin.data.schema.resolver.ClasspathResourceDataSchemaResolver) DataSchemaResolver(com.linkedin.data.schema.DataSchemaResolver) ResourceModel(com.linkedin.restli.internal.server.model.ResourceModel) ClasspathResourceDataSchemaResolver(com.linkedin.data.schema.resolver.ClasspathResourceDataSchemaResolver) Test(org.testng.annotations.Test)

Example 43 with ResourceModel

use of com.linkedin.restli.internal.server.model.ResourceModel 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
 * @return An instance of key's corresponding type
 */
private static Object parseEntityStringKey(final String stringKey, final RoutingResult routingResult) {
    ResourceModel resourceModel = routingResult.getResourceMethod().getResourceModel();
    ServerResourceContext resourceContext = routingResult.getContext();
    ProtocolVersion version = resourceContext.getRestliProtocolVersion();
    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, routingResult.getResourceMethodConfig().shouldValidateResourceKeys()), altKeyName, resourceModel);
        } else if (ComplexResourceKey.class.equals(primaryKey.getType())) {
            ComplexResourceKey<RecordTemplate, RecordTemplate> complexKey = ComplexResourceKey.parseString(stringKey, ComplexKeySpec.forClassesMaybeNull(resourceModel.getKeyKeyClass(), resourceModel.getKeyParamsClass()), version);
            if (routingResult.getResourceMethodConfig().shouldValidateResourceKeys()) {
                complexKey.validate();
            }
            return complexKey;
        } else if (CompoundKey.class.equals(primaryKey.getType())) {
            return ArgumentUtils.parseCompoundKey(stringKey, resourceModel.getKeys(), version, routingResult.getResourceMethodConfig().shouldValidateResourceKeys());
        } 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(), routingResult.getResourceMethodConfig().shouldValidateResourceKeys());
        }
    } 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) InvalidAlternativeKeyException(com.linkedin.data.template.InvalidAlternativeKeyException) ServerResourceContext(com.linkedin.restli.internal.server.ServerResourceContext) AlternativeKeyCoercerException(com.linkedin.restli.internal.server.util.AlternativeKeyCoercerException) ComplexResourceKey(com.linkedin.restli.common.ComplexResourceKey) ResourceModel(com.linkedin.restli.internal.server.model.ResourceModel) ByteString(com.linkedin.data.ByteString) ProtocolVersion(com.linkedin.restli.common.ProtocolVersion) ComplexResourceKey(com.linkedin.restli.common.ComplexResourceKey) Key(com.linkedin.restli.server.Key) CompoundKey(com.linkedin.restli.common.CompoundKey)

Example 44 with ResourceModel

use of com.linkedin.restli.internal.server.model.ResourceModel in project rest.li by linkedin.

the class RestLiRouter method process.

/**
 * Processes provided {@link Request}.
 */
public ResourceMethodDescriptor process(final ServerResourceContext context) {
    String path = context.getRequestURI().getRawPath();
    if (path.length() < 2) {
        throw new RoutingException(HttpStatus.S_404_NOT_FOUND.getCode());
    }
    if (path.charAt(0) == '/') {
        path = path.substring(1);
    }
    Queue<String> remainingPath = new LinkedList<>(Arrays.asList(SLASH_PATTERN.split(path)));
    String rootPath = "/" + remainingPath.poll();
    ResourceModel currentResource;
    try {
        currentResource = _pathRootResourceMap.get(URLDecoder.decode(rootPath, RestConstants.DEFAULT_CHARSET_NAME));
    } catch (UnsupportedEncodingException e) {
        throw new RestLiInternalException("UnsupportedEncodingException while trying to decode the root path", e);
    }
    if (currentResource == null) {
        throw new RoutingException(String.format("No root resource defined for path '%s'", rootPath), HttpStatus.S_404_NOT_FOUND.getCode());
    }
    return processResourceTree(currentResource, context, remainingPath);
}
Also used : RoutingException(com.linkedin.restli.server.RoutingException) ResourceModel(com.linkedin.restli.internal.server.model.ResourceModel) UnsupportedEncodingException(java.io.UnsupportedEncodingException) LinkedList(java.util.LinkedList)

Example 45 with ResourceModel

use of com.linkedin.restli.internal.server.model.ResourceModel 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) ByteString(com.linkedin.data.ByteString)

Aggregations

ResourceModel (com.linkedin.restli.internal.server.model.ResourceModel)223 Test (org.testng.annotations.Test)190 ResourceMethodDescriptor (com.linkedin.restli.internal.server.model.ResourceMethodDescriptor)161 RestLiTestHelper.buildResourceModel (com.linkedin.restli.server.test.RestLiTestHelper.buildResourceModel)139 AfterTest (org.testng.annotations.AfterTest)114 BeforeTest (org.testng.annotations.BeforeTest)114 ByteString (com.linkedin.data.ByteString)50 PromiseStatusCollectionResource (com.linkedin.restli.server.twitter.PromiseStatusCollectionResource)50 CustomString (com.linkedin.restli.server.custom.types.CustomString)43 AsyncStatusCollectionResource (com.linkedin.restli.server.twitter.AsyncStatusCollectionResource)40 ServerResourceContext (com.linkedin.restli.internal.server.ServerResourceContext)37 RestRequest (com.linkedin.r2.message.rest.RestRequest)36 Callback (com.linkedin.common.callback.Callback)34 RestLiConfig (com.linkedin.restli.server.RestLiConfig)34 RestLiRouter (com.linkedin.restli.internal.server.RestLiRouter)32 RequestContext (com.linkedin.r2.message.RequestContext)29 RestLiCallback (com.linkedin.restli.internal.server.RestLiCallback)28 RoutingResult (com.linkedin.restli.internal.server.RoutingResult)28 FilterChainCallback (com.linkedin.restli.internal.server.filter.FilterChainCallback)28 TaskStatusCollectionResource (com.linkedin.restli.server.twitter.TaskStatusCollectionResource)28