Search in sources :

Example 11 with PagingContext

use of com.linkedin.restli.server.PagingContext 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;
}
Also used : RoutingException(com.linkedin.restli.server.RoutingException) HeaderParam(com.linkedin.restli.server.annotations.HeaderParam) DataMap(com.linkedin.data.DataMap) QueryParamsDataMap(com.linkedin.restli.internal.common.QueryParamsDataMap) RestLiServiceException(com.linkedin.restli.server.RestLiServiceException) RestLiDataValidator(com.linkedin.restli.common.validation.RestLiDataValidator) ServerResourceContext(com.linkedin.restli.internal.server.ServerResourceContext) PagingContext(com.linkedin.restli.server.PagingContext) TemplateRuntimeException(com.linkedin.data.template.TemplateRuntimeException) Parameter(com.linkedin.restli.internal.server.model.Parameter) ResourceConfigException(com.linkedin.restli.server.ResourceConfigException)

Example 12 with PagingContext

use of com.linkedin.restli.server.PagingContext in project rest.li by linkedin.

the class TestRestLiMethodInvocation method testPromiseFinderOnComplexKey.

@Test(dataProvider = TestConstants.RESTLI_PROTOCOL_1_2_PREFIX + "discoveredItemsFinder")
public void testPromiseFinderOnComplexKey(ProtocolVersion version, String query) throws Exception {
    ResourceModel discoveredItemsResourceModel = buildResourceModel(PromiseDiscoveredItemsResource.class);
    ResourceMethodDescriptor methodDescriptor = discoveredItemsResourceModel.findNamedMethod("user");
    PromiseDiscoveredItemsResource discoveredItemsResource = getMockResource(PromiseDiscoveredItemsResource.class);
    EasyMock.expect(discoveredItemsResource.getDiscoveredItemsForUser(eq(1L), (PagingContext) EasyMock.anyObject())).andReturn(Promises.<List<DiscoveredItem>>value(null)).once();
    checkInvocation(discoveredItemsResource, methodDescriptor, "GET", version, "/promiseDiscoveredItems" + query);
}
Also used : PagingContext(com.linkedin.restli.server.PagingContext) ResourceMethodDescriptor(com.linkedin.restli.internal.server.model.ResourceMethodDescriptor) ResourceModel(com.linkedin.restli.internal.server.model.ResourceModel) RestLiTestHelper.buildResourceModel(com.linkedin.restli.server.test.RestLiTestHelper.buildResourceModel) List(java.util.List) PromiseDiscoveredItemsResource(com.linkedin.restli.server.twitter.PromiseDiscoveredItemsResource) Test(org.testng.annotations.Test) AfterTest(org.testng.annotations.AfterTest) BeforeTest(org.testng.annotations.BeforeTest)

Example 13 with PagingContext

use of com.linkedin.restli.server.PagingContext in project rest.li by linkedin.

the class TestRestLiMethodInvocation method testGet.

@Test
public void testGet() throws Exception {
    Map<String, ResourceModel> resourceModelMap = buildResourceModels(StatusCollectionResource.class, LocationResource.class, DiscoveredItemsResource.class);
    ResourceModel statusResourceModel = resourceModelMap.get("/statuses");
    ResourceModel discoveredItemsResourceModel = resourceModelMap.get("/discovereditems");
    ResourceMethodDescriptor methodDescriptor;
    StatusCollectionResource statusResource;
    DiscoveredItemsResource discoveredItemsResource;
    // #1: simple filter
    methodDescriptor = statusResourceModel.findNamedMethod("public_timeline");
    statusResource = getMockResource(StatusCollectionResource.class);
    EasyMock.expect(statusResource.getPublicTimeline((PagingContext) EasyMock.anyObject())).andReturn(null).once();
    checkInvocation(statusResource, methodDescriptor, "GET", version, "/statuses?q=public_timeline");
    // #2: get
    methodDescriptor = statusResourceModel.findMethod(ResourceMethod.GET);
    statusResource = getMockResource(StatusCollectionResource.class);
    EasyMock.expect(statusResource.get(eq(1L))).andReturn(null).once();
    checkInvocation(statusResource, methodDescriptor, "GET", version, "/statuses/1", buildPathKeys("statusID", 1L));
    // #3: get simple sub-resource
    ResourceModel locationResourceModel = statusResourceModel.getSubResource("location");
    LocationResource locationResource;
    methodDescriptor = locationResourceModel.findMethod(ResourceMethod.GET);
    locationResource = getMockResource(LocationResource.class);
    EasyMock.expect(locationResource.get()).andReturn(null).once();
    checkInvocation(locationResource, methodDescriptor, "GET", version, "/statuses/1/location", buildPathKeys("statusID", 1L));
    // #4: get complex-key resource
    methodDescriptor = discoveredItemsResourceModel.findMethod(ResourceMethod.GET);
    discoveredItemsResource = getMockResource(DiscoveredItemsResource.class);
    ComplexResourceKey<DiscoveredItemKey, DiscoveredItemKeyParams> key = getDiscoveredItemComplexKey(1L, 2, 3L);
    EasyMock.expect(discoveredItemsResource.get(eq(key))).andReturn(null).once();
    checkInvocation(discoveredItemsResource, methodDescriptor, "GET", version, "/discovereditems/(itemId:1,type:2,userId:3)", buildPathKeys("discoveredItemId", key));
}
Also used : DiscoveredItemKeyParams(com.linkedin.restli.server.twitter.TwitterTestDataModels.DiscoveredItemKeyParams) PagingContext(com.linkedin.restli.server.PagingContext) ResourceMethodDescriptor(com.linkedin.restli.internal.server.model.ResourceMethodDescriptor) ResourceModel(com.linkedin.restli.internal.server.model.ResourceModel) RestLiTestHelper.buildResourceModel(com.linkedin.restli.server.test.RestLiTestHelper.buildResourceModel) TaskStatusCollectionResource(com.linkedin.restli.server.twitter.TaskStatusCollectionResource) StatusCollectionResource(com.linkedin.restli.server.twitter.StatusCollectionResource) AsyncStatusCollectionResource(com.linkedin.restli.server.twitter.AsyncStatusCollectionResource) CustomStatusCollectionResource(com.linkedin.restli.server.twitter.CustomStatusCollectionResource) PromiseStatusCollectionResource(com.linkedin.restli.server.twitter.PromiseStatusCollectionResource) ByteString(com.linkedin.data.ByteString) CustomString(com.linkedin.restli.server.custom.types.CustomString) AsyncDiscoveredItemsResource(com.linkedin.restli.server.twitter.AsyncDiscoveredItemsResource) PromiseDiscoveredItemsResource(com.linkedin.restli.server.twitter.PromiseDiscoveredItemsResource) DiscoveredItemsResource(com.linkedin.restli.server.twitter.DiscoveredItemsResource) DiscoveredItemKey(com.linkedin.restli.server.twitter.TwitterTestDataModels.DiscoveredItemKey) LocationResource(com.linkedin.restli.server.twitter.LocationResource) PromiseLocationResource(com.linkedin.restli.server.twitter.PromiseLocationResource) AsyncLocationResource(com.linkedin.restli.server.twitter.AsyncLocationResource) Test(org.testng.annotations.Test) AfterTest(org.testng.annotations.AfterTest) BeforeTest(org.testng.annotations.BeforeTest)

Example 14 with PagingContext

use of com.linkedin.restli.server.PagingContext in project rest.li by linkedin.

the class TestRestLiMethodInvocation method testPromisePagingContextUserTimelineDefault.

@Test(dataProvider = TestConstants.RESTLI_PROTOCOL_1_2_PREFIX + "statusUserTimelineDefault")
public void testPromisePagingContextUserTimelineDefault(ProtocolVersion version, String query) throws Exception {
    ResourceModel statusResourceModel = buildResourceModel(PromiseStatusCollectionResource.class);
    ResourceMethodDescriptor methodDescriptor = statusResourceModel.findNamedMethod("user_timeline");
    PromiseStatusCollectionResource statusResource = getMockResource(PromiseStatusCollectionResource.class);
    EasyMock.expect(statusResource.getUserTimeline(eq(true), eq(new PagingContext(10, 100, false, false)))).andReturn(Promises.<List<Status>>value(null)).once();
    checkInvocation(statusResource, methodDescriptor, "GET", version, "/promisestatuses" + query);
}
Also used : PromiseStatusCollectionResource(com.linkedin.restli.server.twitter.PromiseStatusCollectionResource) PagingContext(com.linkedin.restli.server.PagingContext) ResourceMethodDescriptor(com.linkedin.restli.internal.server.model.ResourceMethodDescriptor) ResourceModel(com.linkedin.restli.internal.server.model.ResourceModel) RestLiTestHelper.buildResourceModel(com.linkedin.restli.server.test.RestLiTestHelper.buildResourceModel) List(java.util.List) Test(org.testng.annotations.Test) AfterTest(org.testng.annotations.AfterTest) BeforeTest(org.testng.annotations.BeforeTest)

Example 15 with PagingContext

use of com.linkedin.restli.server.PagingContext in project rest.li by linkedin.

the class TestRestLiMethodInvocation method testAsyncGetAll.

@Test
public void testAsyncGetAll() throws Exception {
    ResourceModel statusResourceModel = buildResourceModel(AsyncStatusCollectionResource.class);
    RestLiCallback<?> callback = getCallback();
    ResourceMethodDescriptor methodDescriptor;
    AsyncStatusCollectionResource statusResource;
    methodDescriptor = statusResourceModel.findMethod(ResourceMethod.GET_ALL);
    statusResource = getMockResource(AsyncStatusCollectionResource.class);
    @SuppressWarnings("unchecked") PagingContext mockCtx = (PagingContext) EasyMock.anyObject();
    statusResource.getAll(mockCtx, EasyMock.<Callback<List<Status>>>anyObject());
    EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {

        @Override
        public Object answer() throws Throwable {
            @SuppressWarnings("unchecked") Callback<List<Status>> callback = (Callback<List<Status>>) EasyMock.getCurrentArguments()[1];
            callback.onSuccess(null);
            return null;
        }
    });
    EasyMock.replay(statusResource);
    checkAsyncInvocation(statusResource, callback, methodDescriptor, "GET", version, "/asyncstatuses", "{}", null);
}
Also used : Status(com.linkedin.restli.server.twitter.TwitterTestDataModels.Status) HttpStatus(com.linkedin.restli.common.HttpStatus) ResourceMethodDescriptor(com.linkedin.restli.internal.server.model.ResourceMethodDescriptor) AsyncStatusCollectionResource(com.linkedin.restli.server.twitter.AsyncStatusCollectionResource) Callback(com.linkedin.common.callback.Callback) RestLiCallback(com.linkedin.restli.internal.server.RestLiCallback) FilterChainCallback(com.linkedin.restli.internal.server.filter.FilterChainCallback) RequestExecutionCallback(com.linkedin.restli.server.RequestExecutionCallback) PagingContext(com.linkedin.restli.server.PagingContext) ResourceModel(com.linkedin.restli.internal.server.model.ResourceModel) RestLiTestHelper.buildResourceModel(com.linkedin.restli.server.test.RestLiTestHelper.buildResourceModel) List(java.util.List) EasyMock.anyObject(org.easymock.EasyMock.anyObject) Test(org.testng.annotations.Test) AfterTest(org.testng.annotations.AfterTest) BeforeTest(org.testng.annotations.BeforeTest)

Aggregations

PagingContext (com.linkedin.restli.server.PagingContext)19 Test (org.testng.annotations.Test)14 ResourceMethodDescriptor (com.linkedin.restli.internal.server.model.ResourceMethodDescriptor)12 ResourceModel (com.linkedin.restli.internal.server.model.ResourceModel)11 RestLiTestHelper.buildResourceModel (com.linkedin.restli.server.test.RestLiTestHelper.buildResourceModel)11 AfterTest (org.testng.annotations.AfterTest)11 BeforeTest (org.testng.annotations.BeforeTest)11 PromiseStatusCollectionResource (com.linkedin.restli.server.twitter.PromiseStatusCollectionResource)8 List (java.util.List)7 Parameter (com.linkedin.restli.internal.server.model.Parameter)5 AsyncStatusCollectionResource (com.linkedin.restli.server.twitter.AsyncStatusCollectionResource)5 ServerResourceContext (com.linkedin.restli.internal.server.ServerResourceContext)3 CustomStatusCollectionResource (com.linkedin.restli.server.twitter.CustomStatusCollectionResource)3 PromiseDiscoveredItemsResource (com.linkedin.restli.server.twitter.PromiseDiscoveredItemsResource)3 StatusCollectionResource (com.linkedin.restli.server.twitter.StatusCollectionResource)3 TaskStatusCollectionResource (com.linkedin.restli.server.twitter.TaskStatusCollectionResource)3 Callback (com.linkedin.common.callback.Callback)2 ByteString (com.linkedin.data.ByteString)2 DataMap (com.linkedin.data.DataMap)2 StringDataSchema (com.linkedin.data.schema.StringDataSchema)2