/** * @param request {@link RestRequest} * @param routingResult {@link RoutingResult} * @param responseObject response value * @return {@link RestResponse} * @throws IOException if cannot build response */ public RestResponse buildResponse( final RestRequest request, final RoutingResult routingResult, final Object responseObject) throws IOException { Map<String, String> headers = new HashMap<String, String>(); headers.putAll(((ServerResourceContext) routingResult.getContext()).getResponseHeaders()); headers.put( RestConstants.HEADER_RESTLI_PROTOCOL_VERSION, ((ServerResourceContext) routingResult.getContext()).getRestliProtocolVersion().toString()); if (responseObject == null) { boolean isAction = routingResult.getResourceMethod().getType().equals(ResourceMethod.ACTION); RestResponseBuilder builder = new RestResponseBuilder(); builder.setStatus( isAction ? HttpStatus.S_200_OK.getCode() : HttpStatus.S_404_NOT_FOUND.getCode()); builder.setHeaders(headers); if (!isAction) { builder.setHeader( RestConstants.HEADER_LINKEDIN_ERROR_RESPONSE, RestConstants.HEADER_VALUE_ERROR_APPLICATION); } return builder.build(); } RestLiResponseBuilder responseBuilder = chooseResponseBuilder(responseObject, routingResult); if (responseBuilder == null) { // this should not happen if valid return types are specified ResourceMethodDescriptor resourceMethod = routingResult.getResourceMethod(); String fqMethodName = resourceMethod.getResourceModel().getResourceClass().getName() + '#' + routingResult.getResourceMethod().getMethod().getName(); throw new RestLiInternalException( "Invalid return type '" + responseObject.getClass() + " from method '" + fqMethodName + '\''); } PartialRestResponse partialResponse = responseBuilder.buildResponse(request, routingResult, responseObject, headers); RestResponseBuilder builder = new RestResponseBuilder() .setHeaders(headers) .setStatus(partialResponse.getStatus().getCode()); if (partialResponse.hasData()) { DataMap dataMap = partialResponse.getDataMap(); String acceptTypes = request.getHeader(RestConstants.HEADER_ACCEPT); builder = encodeResult(builder, dataMap, acceptTypes); } return builder.build(); }
private RestLiResponseBuilder chooseResponseBuilder( final Object responseObject, final RoutingResult routingResult) { if (responseObject instanceof RestLiServiceException) { return _errorResponseBuilder; } return _methodAdapterRegistry.getResponsebuilder(routingResult.getResourceMethod().getType()); }
@Override public void onSuccess(RestLiRequestData requestData) { try { ResourceMethodDescriptor resourceMethodDescriptor = _invocableMethod.getResourceMethod(); Object resource = _resourceFactory.create(resourceMethodDescriptor.getResourceModel().getResourceClass()); if (BaseResource.class.isAssignableFrom(resource.getClass())) { ((BaseResource) resource).setContext(_invocableMethod.getContext()); } Object[] args = _restLiArgumentBuilder.buildArguments(requestData, _invocableMethod); // Now invoke the resource implementation. doInvoke( resourceMethodDescriptor, _callback, _requestExecutionReportBuilder, resource, args); } catch (Exception e) { _callback.onError( e, _requestExecutionReportBuilder == null ? null : _requestExecutionReportBuilder.build()); } }
/** * Invokes the method with the specified callback and arguments built from the request. * * @param invocableMethod {@link RoutingResult} * @param request {@link RestRequest} * @param callback {@link RestLiCallback} * @param isDebugMode whether the invocation will be done as part of a debug request. * @param filterContext {@link FilterRequestContextInternal} */ public void invoke( final RoutingResult invocableMethod, final RestRequest request, final RequestExecutionCallback<Object> callback, final boolean isDebugMode, final FilterRequestContextInternal filterContext) { RequestExecutionReportBuilder requestExecutionReportBuilder = null; if (isDebugMode) { requestExecutionReportBuilder = new RequestExecutionReportBuilder(); } // Fast fail if the request headers are invalid. try { RestUtils.validateRequestHeadersAndUpdateResourceContext( request.getHeaders(), (ServerResourceContext) invocableMethod.getContext()); } catch (RestLiServiceException e) { callback.onError(e, getRequestExecutionReport(requestExecutionReportBuilder)); return; } // Request headers are valid. Proceed with the invocation of the filters and eventually the // resource. ResourceMethodDescriptor resourceMethodDescriptor = invocableMethod.getResourceMethod(); RestLiArgumentBuilder adapter = _methodAdapterRegistry.getArgumentBuilder(resourceMethodDescriptor.getType()); if (adapter == null) { throw new IllegalArgumentException( "Unsupported method type: " + resourceMethodDescriptor.getType()); } RestLiRequestData requestData = adapter.extractRequestData(invocableMethod, request); filterContext.setRequestData(requestData); // Kick off the request filter iterator, which finally would invoke the resource. RestLiRequestFilterChainCallback restLiRequestFilterChainCallback = new RestLiRequestFilterChainCallbackImpl( invocableMethod, adapter, callback, requestExecutionReportBuilder); new RestLiRequestFilterChain(_requestFilters, restLiRequestFilterChainCallback) .onRequest(filterContext); }