Search in sources :

Example 1 with UpdateEntityResponse

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

the class PartialUpdateResponseBuilder method buildRestLiResponseData.

@Override
@SuppressWarnings({ "unchecked" })
public RestLiResponseData<PartialUpdateResponseEnvelope> buildRestLiResponseData(Request request, RoutingResult routingResult, Object result, Map<String, String> headers, List<HttpCookie> cookies) {
    UpdateResponse updateResponse = (UpdateResponse) result;
    // Verify that the status in the UpdateResponse is not null. If so, this is a developer error.
    if (updateResponse.getStatus() == null) {
        throw new RestLiServiceException(HttpStatus.S_500_INTERNAL_SERVER_ERROR, "Unexpected null encountered. HttpStatus is null inside of an UpdateResponse returned by the resource method: " + routingResult.getResourceMethod());
    }
    final ResourceContext resourceContext = routingResult.getContext();
    RecordTemplate entityResponse = null;
    // Add patched entity to the response if result is an UpdateEntityResponse and the client is asking for the entity
    if (result instanceof UpdateEntityResponse && resourceContext.isReturnEntityRequested()) {
        UpdateEntityResponse<?> updateEntityResponse = (UpdateEntityResponse<?>) updateResponse;
        if (updateEntityResponse.hasEntity()) {
            DataMap entityData = updateEntityResponse.getEntity().data();
            TimingContextUtil.beginTiming(resourceContext.getRawRequestContext(), FrameworkTimingKeys.SERVER_RESPONSE_RESTLI_PROJECTION_APPLY.key());
            final DataMap data = RestUtils.projectFields(entityData, resourceContext);
            TimingContextUtil.endTiming(resourceContext.getRawRequestContext(), FrameworkTimingKeys.SERVER_RESPONSE_RESTLI_PROJECTION_APPLY.key());
            // Returned entity is to be added to the response envelope
            entityResponse = new EntityResponse<>(data, updateEntityResponse.getEntity().getClass());
        } else {
            // If trying to return an error response, a RestLiServiceException should be thrown in the resource method.
            throw new RestLiServiceException(HttpStatus.S_500_INTERNAL_SERVER_ERROR, "Unexpected null encountered. Entity is null inside of an UpdateEntityResponse returned by the resource method: " + routingResult.getResourceMethod());
        }
    }
    return new RestLiResponseDataImpl<>(new PartialUpdateResponseEnvelope(updateResponse.getStatus(), entityResponse), headers, cookies);
}
Also used : UpdateResponse(com.linkedin.restli.server.UpdateResponse) ResourceContext(com.linkedin.restli.server.ResourceContext) RestLiServiceException(com.linkedin.restli.server.RestLiServiceException) RecordTemplate(com.linkedin.data.template.RecordTemplate) UpdateEntityResponse(com.linkedin.restli.server.UpdateEntityResponse) DataMap(com.linkedin.data.DataMap)

Example 2 with UpdateEntityResponse

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

the class TestBatchPartialUpdateResponseBuilder method testProjectionInBuildRestLiResponseData.

/**
 * Ensures that the returned entities are properly projected when a projection mask is passed into the response builder.
 */
@Test
@SuppressWarnings("unchecked")
public void testProjectionInBuildRestLiResponseData() {
    final Long id = 1L;
    TestRecord record = new TestRecord().setIntField(2147).setDoubleField(21.47).setFloatField(123F).setLongField(456L);
    BatchUpdateEntityResult<Long, TestRecord> result = new BatchUpdateEntityResult<>(Collections.singletonMap(id, new UpdateEntityResponse<>(HttpStatus.S_200_OK, record)));
    MaskTree maskTree = new MaskTree();
    maskTree.addOperation(new PathSpec("intField"), MaskOperation.POSITIVE_MASK_OP);
    Map<String, String> headers = ResponseBuilderUtil.getHeaders();
    RoutingResult routingResult = getMockRoutingResult(true, maskTree);
    BatchPartialUpdateResponseBuilder batchPartialUpdateResponseBuilder = new BatchPartialUpdateResponseBuilder(new ErrorResponseBuilder());
    RestLiResponseData<BatchPartialUpdateResponseEnvelope> responseData = batchPartialUpdateResponseBuilder.buildRestLiResponseData(null, routingResult, result, headers, Collections.emptyList());
    UpdateEntityStatus<TestRecord> updateEntityStatus = (UpdateEntityStatus<TestRecord>) responseData.getResponseEnvelope().getBatchResponseMap().get(id).getRecord();
    Assert.assertNotNull(updateEntityStatus);
    RecordTemplate returnedRecord = updateEntityStatus.getEntity();
    Assert.assertEquals(returnedRecord.data().size(), 1, "Expected response record to be projected down to one field.");
    Assert.assertEquals((int) returnedRecord.data().get("intField"), 2147, "Expected response record intField to match original.");
}
Also used : UpdateEntityStatus(com.linkedin.restli.common.UpdateEntityStatus) BatchUpdateEntityResult(com.linkedin.restli.server.BatchUpdateEntityResult) PathSpec(com.linkedin.data.schema.PathSpec) RoutingResult(com.linkedin.restli.internal.server.RoutingResult) MaskTree(com.linkedin.data.transform.filter.request.MaskTree) UpdateEntityResponse(com.linkedin.restli.server.UpdateEntityResponse) RecordTemplate(com.linkedin.data.template.RecordTemplate) TestRecord(com.linkedin.restli.server.TestRecord) Test(org.testng.annotations.Test)

Example 3 with UpdateEntityResponse

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

the class TestPartialUpdateResponseBuilder method testProjectionInBuildRestLiResponseData.

/**
 * Ensures that the returned entity is properly projected when a projection mask is passed into the response builder.
 */
@Test
public void testProjectionInBuildRestLiResponseData() {
    TestRecord record = new TestRecord().setIntField(2147).setDoubleField(21.47).setFloatField(123F).setLongField(456L);
    UpdateEntityResponse<TestRecord> response = new UpdateEntityResponse<>(HttpStatus.S_200_OK, record);
    MaskTree maskTree = new MaskTree();
    maskTree.addOperation(new PathSpec("intField"), MaskOperation.POSITIVE_MASK_OP);
    Map<String, String> headers = ResponseBuilderUtil.getHeaders();
    RoutingResult routingResult = getMockRoutingResult(true, maskTree);
    PartialUpdateResponseBuilder partialUpdateResponseBuilder = new PartialUpdateResponseBuilder();
    RestLiResponseData<PartialUpdateResponseEnvelope> responseData = partialUpdateResponseBuilder.buildRestLiResponseData(null, routingResult, response, headers, Collections.emptyList());
    RecordTemplate returnedRecord = responseData.getResponseEnvelope().getRecord();
    Assert.assertEquals(returnedRecord.data().size(), 1, "Expected response record to be projected down to one field.");
    Assert.assertEquals(returnedRecord.data().get("intField"), 2147, "Expected response record intField to match original.");
}
Also used : RoutingResult(com.linkedin.restli.internal.server.RoutingResult) MaskTree(com.linkedin.data.transform.filter.request.MaskTree) UpdateEntityResponse(com.linkedin.restli.server.UpdateEntityResponse) RecordTemplate(com.linkedin.data.template.RecordTemplate) TestRecord(com.linkedin.restli.server.TestRecord) PathSpec(com.linkedin.data.schema.PathSpec) Test(org.testng.annotations.Test)

Example 4 with UpdateEntityResponse

use of com.linkedin.restli.server.UpdateEntityResponse 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 5 with UpdateEntityResponse

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

the class BatchPartialUpdateResponseBuilder method buildUpdateStatus.

/**
 * Defines how to build an update status for batch partial update. If the update response is an {@link UpdateEntityResponse}
 * and the client is requesting the entities to be returned, then build an {@link UpdateEntityStatus} containing the
 * entity to be returned for a given update response.
 * @param resourceContext current resource context
 * @param updateResponse update response returned by the resource method
 * @return update status possibly containing the returned entity
 */
@Override
protected UpdateStatus buildUpdateStatus(ResourceContext resourceContext, UpdateResponse updateResponse) {
    if (updateResponse instanceof UpdateEntityResponse && resourceContext.isReturnEntityRequested()) {
        final RecordTemplate entity = ((UpdateEntityResponse<?>) updateResponse).getEntity();
        final DataMap entityData = entity != null ? entity.data() : null;
        final DataMap projectedData = RestUtils.projectFields(entityData, resourceContext);
        return new UpdateEntityStatus<>(updateResponse.getStatus().getCode(), new AnyRecord(projectedData));
    } else {
        return super.buildUpdateStatus(resourceContext, updateResponse);
    }
}
Also used : UpdateEntityStatus(com.linkedin.restli.common.UpdateEntityStatus) AnyRecord(com.linkedin.restli.internal.server.methods.AnyRecord) UpdateEntityResponse(com.linkedin.restli.server.UpdateEntityResponse) RecordTemplate(com.linkedin.data.template.RecordTemplate) DataMap(com.linkedin.data.DataMap)

Aggregations

UpdateEntityResponse (com.linkedin.restli.server.UpdateEntityResponse)5 RecordTemplate (com.linkedin.data.template.RecordTemplate)4 DataMap (com.linkedin.data.DataMap)2 PathSpec (com.linkedin.data.schema.PathSpec)2 MaskTree (com.linkedin.data.transform.filter.request.MaskTree)2 UpdateEntityStatus (com.linkedin.restli.common.UpdateEntityStatus)2 RoutingResult (com.linkedin.restli.internal.server.RoutingResult)2 BatchUpdateEntityResult (com.linkedin.restli.server.BatchUpdateEntityResult)2 RestLiServiceException (com.linkedin.restli.server.RestLiServiceException)2 TestRecord (com.linkedin.restli.server.TestRecord)2 Test (org.testng.annotations.Test)2 PatchRequest (com.linkedin.restli.common.PatchRequest)1 InstrumentationControl (com.linkedin.restli.examples.instrumentation.api.InstrumentationControl)1 AnyRecord (com.linkedin.restli.internal.server.methods.AnyRecord)1 BatchPatchRequest (com.linkedin.restli.server.BatchPatchRequest)1 ResourceContext (com.linkedin.restli.server.ResourceContext)1 UpdateResponse (com.linkedin.restli.server.UpdateResponse)1 ReturnEntity (com.linkedin.restli.server.annotations.ReturnEntity)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1