Search in sources :

Example 96 with RestLiServiceException

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

the class RestLiMethodInvoker method doInvoke.

@SuppressWarnings("deprecation")
private void doInvoke(final ResourceMethodDescriptor descriptor, final RequestExecutionCallback<Object> callback, final RequestExecutionReportBuilder requestExecutionReportBuilder, final Object resource, final ServerResourceContext resourceContext, final Object... arguments) throws IllegalAccessException {
    final Method method = descriptor.getMethod();
    try {
        switch(descriptor.getInterfaceType()) {
            case CALLBACK:
                int callbackIndex = descriptor.indexOfParameterType(ParamType.CALLBACK);
                final RequestExecutionReport executionReport = getRequestExecutionReport(requestExecutionReportBuilder);
                //Delegate the callback call to the request execution callback along with the
                //request execution report.
                arguments[callbackIndex] = new Callback<Object>() {

                    @Override
                    public void onError(Throwable e) {
                        callback.onError(e instanceof RestLiServiceException ? e : new RestLiServiceException(HttpStatus.S_500_INTERNAL_SERVER_ERROR, e), executionReport, resourceContext.getRequestAttachmentReader(), resourceContext.getResponseAttachments());
                    }

                    @Override
                    public void onSuccess(Object result) {
                        callback.onSuccess(result, executionReport, resourceContext.getResponseAttachments());
                    }
                };
                method.invoke(resource, arguments);
                // App code should use the callback
                break;
            case SYNC:
                Object applicationResult = method.invoke(resource, arguments);
                callback.onSuccess(applicationResult, getRequestExecutionReport(requestExecutionReportBuilder), resourceContext.getResponseAttachments());
                break;
            case PROMISE:
                if (!checkEngine(resourceContext, callback, descriptor, requestExecutionReportBuilder)) {
                    break;
                }
                int contextIndex = descriptor.indexOfParameterType(ParamType.PARSEQ_CONTEXT_PARAM);
                if (contextIndex == -1) {
                    contextIndex = descriptor.indexOfParameterType(ParamType.PARSEQ_CONTEXT);
                }
                // run through the engine to get the context
                Task<Object> restliTask = new RestLiParSeqTask(arguments, contextIndex, method, resource);
                // propagate the result to the callback
                restliTask.addListener(new CallbackPromiseAdapter<>(callback, restliTask, requestExecutionReportBuilder, resourceContext.getRequestAttachmentReader(), resourceContext.getResponseAttachments()));
                runTask(restliTask, toPlanClass(descriptor));
                break;
            case TASK:
                if (!checkEngine(resourceContext, callback, descriptor, requestExecutionReportBuilder)) {
                    break;
                }
                //addListener requires Task<Object> in this case
                @SuppressWarnings("unchecked") Task<Object> task = (Task<Object>) method.invoke(resource, arguments);
                if (task == null) {
                    callback.onError(new RestLiServiceException(HttpStatus.S_500_INTERNAL_SERVER_ERROR, "Error in application code: null Task"), getRequestExecutionReport(requestExecutionReportBuilder), resourceContext.getRequestAttachmentReader(), resourceContext.getResponseAttachments());
                } else {
                    task.addListener(new CallbackPromiseAdapter<>(callback, task, requestExecutionReportBuilder, resourceContext.getRequestAttachmentReader(), resourceContext.getResponseAttachments()));
                    runTask(task, toPlanClass(descriptor));
                }
                break;
            default:
                throw new AssertionError("Unexpected interface type " + descriptor.getInterfaceType());
        }
    } catch (InvocationTargetException e) {
        // InvocationTargetException wrapped around the root cause.
        if (RestLiServiceException.class.isAssignableFrom(e.getCause().getClass())) {
            RestLiServiceException restLiServiceException = (RestLiServiceException) e.getCause();
            callback.onError(restLiServiceException, getRequestExecutionReport(requestExecutionReportBuilder), resourceContext.getRequestAttachmentReader(), resourceContext.getResponseAttachments());
        } else {
            callback.onError(new RestLiServiceException(HttpStatus.S_500_INTERNAL_SERVER_ERROR, _errorResponseBuilder.getInternalErrorMessage(), e.getCause()), getRequestExecutionReport(requestExecutionReportBuilder), resourceContext.getRequestAttachmentReader(), resourceContext.getResponseAttachments());
        }
    }
}
Also used : BaseTask(com.linkedin.parseq.BaseTask) Task(com.linkedin.parseq.Task) Method(java.lang.reflect.Method) RequestExecutionReport(com.linkedin.restli.server.RequestExecutionReport) InvocationTargetException(java.lang.reflect.InvocationTargetException) RestLiServiceException(com.linkedin.restli.server.RestLiServiceException)

Example 97 with RestLiServiceException

use of com.linkedin.restli.server.RestLiServiceException in project incubator-gobblin by apache.

the class LimiterServerResourceTest method testLimitedRequests.

@Test
public void testLimitedRequests() {
    ThrottlingPolicyFactory factory = new ThrottlingPolicyFactory();
    SharedLimiterKey res1key = new SharedLimiterKey("res1");
    SharedLimiterKey res2key = new SharedLimiterKey("res2");
    Map<String, String> configMap = ImmutableMap.<String, String>builder().put(BrokerConfigurationKeyGenerator.generateKey(factory, res1key, null, ThrottlingPolicyFactory.POLICY_KEY), CountBasedPolicy.FACTORY_ALIAS).put(BrokerConfigurationKeyGenerator.generateKey(factory, res1key, null, CountBasedPolicy.COUNT_KEY), "100").put(BrokerConfigurationKeyGenerator.generateKey(factory, res2key, null, ThrottlingPolicyFactory.POLICY_KEY), CountBasedPolicy.FACTORY_ALIAS).put(BrokerConfigurationKeyGenerator.generateKey(factory, res2key, null, CountBasedPolicy.COUNT_KEY), "50").build();
    ThrottlingGuiceServletConfig guiceServletConfig = new ThrottlingGuiceServletConfig();
    guiceServletConfig.initialize(ConfigFactory.parseMap(configMap));
    Injector injector = guiceServletConfig.getInjector();
    LimiterServerResource limiterServer = injector.getInstance(LimiterServerResource.class);
    PermitRequest res1request = new PermitRequest();
    res1request.setPermits(20);
    res1request.setResource(res1key.getResourceLimitedPath());
    PermitRequest res2request = new PermitRequest();
    res2request.setPermits(20);
    res2request.setResource(res2key.getResourceLimitedPath());
    PermitRequest res3request = new PermitRequest();
    res3request.setPermits(100000);
    res3request.setResource("res3");
    Assert.assertEquals(limiterServer.getSync(new ComplexResourceKey<>(res1request, new EmptyRecord())).getPermits(), new Long(20));
    Assert.assertEquals(limiterServer.getSync(new ComplexResourceKey<>(res1request, new EmptyRecord())).getPermits(), new Long(20));
    Assert.assertEquals(limiterServer.getSync(new ComplexResourceKey<>(res1request, new EmptyRecord())).getPermits(), new Long(20));
    Assert.assertEquals(limiterServer.getSync(new ComplexResourceKey<>(res1request, new EmptyRecord())).getPermits(), new Long(20));
    Assert.assertEquals(limiterServer.getSync(new ComplexResourceKey<>(res1request, new EmptyRecord())).getPermits(), new Long(20));
    try {
        // out of permits
        limiterServer.getSync(new ComplexResourceKey<>(res1request, new EmptyRecord())).getPermits();
        Assert.fail();
    } catch (RestLiServiceException exc) {
        Assert.assertEquals(exc.getStatus(), HttpStatus.S_403_FORBIDDEN);
    }
    Assert.assertEquals(limiterServer.getSync(new ComplexResourceKey<>(res2request, new EmptyRecord())).getPermits(), new Long(20));
    Assert.assertEquals(limiterServer.getSync(new ComplexResourceKey<>(res2request, new EmptyRecord())).getPermits(), new Long(20));
    // out of permits
    try {
        // out of permits
        limiterServer.getSync(new ComplexResourceKey<>(res2request, new EmptyRecord())).getPermits();
        Assert.fail();
    } catch (RestLiServiceException exc) {
        Assert.assertEquals(exc.getStatus(), HttpStatus.S_403_FORBIDDEN);
    }
    // No limit
    Assert.assertTrue(limiterServer.getSync(new ComplexResourceKey<>(res3request, new EmptyRecord())).getPermits() >= res3request.getPermits());
}
Also used : EmptyRecord(com.linkedin.restli.common.EmptyRecord) RestLiServiceException(com.linkedin.restli.server.RestLiServiceException) Injector(com.google.inject.Injector) ComplexResourceKey(com.linkedin.restli.common.ComplexResourceKey) SharedLimiterKey(org.apache.gobblin.util.limiter.broker.SharedLimiterKey) Test(org.testng.annotations.Test)

Example 98 with RestLiServiceException

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

the class LatencyInstrumentationResource method create.

/**
 * This is the "upstream endpoint" which is queried directly by the integration test.
 * This endpoint makes a call to {@link #batchPartialUpdate(BatchPatchRequest)} (the "downstream endpoint"),
 * then packs all the client-side timing data into the original server-side request context.
 */
@ReturnEntity
@RestMethod.Create
public CreateKVResponse<Long, InstrumentationControl> create(InstrumentationControl control) {
    final boolean forceException = control.isForceException();
    final boolean useScatterGather = control.isUseScatterGather();
    final String uriPrefix = control.getServiceUriPrefix();
    // Build the downstream request
    final BatchPartialUpdateEntityRequestBuilder<Long, InstrumentationControl> builder = new LatencyInstrumentationBuilders().batchPartialUpdateAndGet();
    final PatchRequest<InstrumentationControl> patch = PatchGenerator.diffEmpty(control);
    for (long i = 0; i < DOWNSTREAM_BATCH_SIZE; i++) {
        builder.input(i, patch);
    }
    final BatchPartialUpdateEntityRequest<Long, InstrumentationControl> request = builder.build();
    // Set up the Rest.li client config
    final RestLiClientConfig clientConfig = new RestLiClientConfig();
    clientConfig.setUseStreaming(control.isUseStreaming());
    if (useScatterGather) {
        clientConfig.setScatterGatherStrategy(new DefaultScatterGatherStrategy(new DummyUriMapper()));
    }
    final TransportClient transportClient = new HttpClientFactory.Builder().build().getClient(Collections.emptyMap());
    final RestClient restClient = new ForceScatterGatherRestClient(new TransportClientAdapter(transportClient), uriPrefix, clientConfig);
    final RequestContext serverRequestContext = getContext().getRawRequestContext();
    final RequestContext clientRequestContext = new RequestContext();
    // Load the timing importance threshold from the server context into the client context
    clientRequestContext.putLocalAttr(TimingContextUtil.TIMING_IMPORTANCE_THRESHOLD_KEY_NAME, serverRequestContext.getLocalAttr(TimingContextUtil.TIMING_IMPORTANCE_THRESHOLD_KEY_NAME));
    try {
        // Make the request, then assert that the returned errors (if any) are as expected
        BatchKVResponse<Long, UpdateEntityStatus<InstrumentationControl>> response = restClient.sendRequest(request, clientRequestContext).getResponseEntity();
        final Map<Long, ErrorResponse> errors = response.getErrors();
        if (forceException && errors.isEmpty()) {
            throw new RestLiServiceException(HttpStatus.S_500_INTERNAL_SERVER_ERROR, "Expected failures for the downstream batch request, but found none.");
        }
        if (!forceException && !errors.isEmpty()) {
            throw new RestLiServiceException(HttpStatus.S_500_INTERNAL_SERVER_ERROR, "Expected no failures for the downstream batch request, but found some.");
        }
        for (ErrorResponse errorResponse : errors.values()) {
            if (!DOWNSTREAM_ERROR_CODE.equals(errorResponse.getCode())) {
                throw new RestLiServiceException(HttpStatus.S_500_INTERNAL_SERVER_ERROR, "Encountered a downstream failure with an unexpected or missing error code.");
            }
        }
    } catch (RemoteInvocationException e) {
        throw new RestLiServiceException(HttpStatus.S_500_INTERNAL_SERVER_ERROR, "Downstream failures should be batch entry failures, but encountered a top-level request failure.", e);
    }
    Map<TimingKey, TimingContextUtil.TimingContext> clientTimingsMap = TimingContextUtil.getTimingsMap(clientRequestContext);
    Map<TimingKey, TimingContextUtil.TimingContext> serverTimingsMap = TimingContextUtil.getTimingsMap(serverRequestContext);
    // Load all client timings into the server timings map
    serverTimingsMap.putAll(clientTimingsMap);
    getContext().setResponseHeader(HAS_CLIENT_TIMINGS_HEADER, Boolean.TRUE.toString());
    if (forceException) {
        throw new RestLiServiceException(HttpStatus.S_400_BAD_REQUEST, "You wanted me to fail, so I failed.").setCode(UPSTREAM_ERROR_CODE);
    }
    return new CreateKVResponse<>(1L, control);
}
Also used : RestLiClientConfig(com.linkedin.restli.client.util.RestLiClientConfig) BatchPartialUpdateEntityRequestBuilder(com.linkedin.restli.client.BatchPartialUpdateEntityRequestBuilder) InstrumentationControl(com.linkedin.restli.examples.instrumentation.api.InstrumentationControl) DefaultScatterGatherStrategy(com.linkedin.restli.client.DefaultScatterGatherStrategy) RestLiServiceException(com.linkedin.restli.server.RestLiServiceException) TimingKey(com.linkedin.r2.message.timing.TimingKey) TransportClientAdapter(com.linkedin.r2.transport.common.bridge.client.TransportClientAdapter) RequestContext(com.linkedin.r2.message.RequestContext) RemoteInvocationException(com.linkedin.r2.RemoteInvocationException) UpdateEntityStatus(com.linkedin.restli.common.UpdateEntityStatus) TransportClient(com.linkedin.r2.transport.common.bridge.client.TransportClient) RestClient(com.linkedin.restli.client.RestClient) LatencyInstrumentationBuilders(com.linkedin.restli.examples.instrumentation.client.LatencyInstrumentationBuilders) ErrorResponse(com.linkedin.restli.common.ErrorResponse) CreateKVResponse(com.linkedin.restli.server.CreateKVResponse) ReturnEntity(com.linkedin.restli.server.annotations.ReturnEntity)

Example 99 with RestLiServiceException

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

the class LatencyInstrumentationResource method batchPartialUpdate.

/**
 * This is the "downstream endpoint", queried by {@link #create(InstrumentationControl)} (the "upstream endpoint").
 */
@ReturnEntity
@RestMethod.BatchPartialUpdate
public BatchUpdateEntityResult<Long, InstrumentationControl> batchPartialUpdate(BatchPatchRequest<Long, InstrumentationControl> batchPatchRequest) throws DataProcessingException {
    final Map<Long, UpdateEntityResponse<InstrumentationControl>> results = new HashMap<>();
    final Map<Long, RestLiServiceException> errors = new HashMap<>();
    for (Map.Entry<Long, PatchRequest<InstrumentationControl>> entry : batchPatchRequest.getData().entrySet()) {
        // Render each patch into a normal record so we know whether or not to force a failure
        InstrumentationControl control = new InstrumentationControl();
        PatchApplier.applyPatch(control, entry.getValue());
        if (control.isForceException()) {
            RestLiServiceException error = new RestLiServiceException(HttpStatus.S_400_BAD_REQUEST, "You wanted me to fail, so I failed.").setCode(DOWNSTREAM_ERROR_CODE);
            errors.put(entry.getKey(), error);
        } else {
            results.put(entry.getKey(), new UpdateEntityResponse<>(HttpStatus.S_200_OK, control));
        }
    }
    return new BatchUpdateEntityResult<>(results, errors);
}
Also used : RestLiServiceException(com.linkedin.restli.server.RestLiServiceException) HashMap(java.util.HashMap) UpdateEntityResponse(com.linkedin.restli.server.UpdateEntityResponse) PatchRequest(com.linkedin.restli.common.PatchRequest) BatchPatchRequest(com.linkedin.restli.server.BatchPatchRequest) HashMap(java.util.HashMap) Map(java.util.Map) BatchUpdateEntityResult(com.linkedin.restli.server.BatchUpdateEntityResult) InstrumentationControl(com.linkedin.restli.examples.instrumentation.api.InstrumentationControl) ReturnEntity(com.linkedin.restli.server.annotations.ReturnEntity)

Example 100 with RestLiServiceException

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

the class GreetingsResourceImpl method batchGet.

@RestMethod.BatchGet
public Map<Long, Greeting> batchGet(Set<Long> ids) {
    Map<Long, Greeting> batch = new HashMap<>();
    Map<Long, RestLiServiceException> errors = new HashMap<>();
    for (long id : ids) {
        Greeting g = _db.get(id);
        if (g != null) {
            batch.put(id, g);
        } else {
            errors.put(id, new RestLiServiceException(HttpStatus.S_404_NOT_FOUND));
        }
    }
    return new BatchResult<>(batch, errors);
}
Also used : Greeting(com.linkedin.restli.examples.greetings.api.Greeting) RestLiServiceException(com.linkedin.restli.server.RestLiServiceException) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) AtomicLong(java.util.concurrent.atomic.AtomicLong) BatchResult(com.linkedin.restli.server.BatchResult)

Aggregations

RestLiServiceException (com.linkedin.restli.server.RestLiServiceException)145 Test (org.testng.annotations.Test)55 HashMap (java.util.HashMap)39 DataMap (com.linkedin.data.DataMap)29 RecordTemplate (com.linkedin.data.template.RecordTemplate)21 Map (java.util.Map)21 RoutingException (com.linkedin.restli.server.RoutingException)20 ServerResourceContext (com.linkedin.restli.internal.server.ServerResourceContext)18 UpdateResponse (com.linkedin.restli.server.UpdateResponse)18 RoutingResult (com.linkedin.restli.internal.server.RoutingResult)17 BeforeTest (org.testng.annotations.BeforeTest)17 FilterRequestContext (com.linkedin.restli.server.filter.FilterRequestContext)16 ArrayList (java.util.ArrayList)16 RestException (com.linkedin.r2.message.rest.RestException)14 FilterResponseContext (com.linkedin.restli.server.filter.FilterResponseContext)13 RestRequest (com.linkedin.r2.message.rest.RestRequest)12 ByteString (com.linkedin.data.ByteString)11 ProtocolVersion (com.linkedin.restli.common.ProtocolVersion)11 ResourceMethodDescriptor (com.linkedin.restli.internal.server.model.ResourceMethodDescriptor)11 BatchResult (com.linkedin.restli.server.BatchResult)11