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;
}
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);
}
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));
}
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);
}
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);
}
Aggregations