Search in sources :

Example 1 with PatchRequest

use of com.linkedin.restli.common.PatchRequest in project rest.li by linkedin.

the class BatchPartialUpdateRequestBuilder method buildReadOnlyInput.

private CollectionRequest<KeyValueRecord<K, PatchRequest<V>>> buildReadOnlyInput() {
    try {
        DataMap map = new DataMap();
        @SuppressWarnings({ "unchecked", "rawtypes" }) CollectionRequest<KeyValueRecord<K, PatchRequest<V>>> input = new CollectionRequest(map, KeyValueRecord.class);
        for (Map.Entry<K, PatchRequest<V>> inputEntityEntry : _partialUpdateInputMap.entrySet()) {
            K key = getReadOnlyOrCopyKey(inputEntityEntry.getKey());
            PatchRequest<V> entity = getReadOnlyOrCopyDataTemplate(inputEntityEntry.getValue());
            KeyValueRecord<K, PatchRequest<V>> keyValueRecord = _keyValueRecordFactory.create(key, entity);
            keyValueRecord.data().setReadOnly();
            input.getElements().add(keyValueRecord);
        }
        map.setReadOnly();
        return input;
    } catch (CloneNotSupportedException cloneException) {
        throw new IllegalArgumentException("Entity cannot be copied.", cloneException);
    }
}
Also used : CollectionRequest(com.linkedin.restli.common.CollectionRequest) PatchRequest(com.linkedin.restli.common.PatchRequest) DataMap(com.linkedin.data.DataMap) KeyValueRecord(com.linkedin.restli.common.KeyValueRecord) HashMap(java.util.HashMap) DataMap(com.linkedin.data.DataMap) Map(java.util.Map)

Example 2 with PatchRequest

use of com.linkedin.restli.common.PatchRequest in project rest.li by linkedin.

the class RestLiDataValidator method validatePatch.

/**
 * Checks that if the patch is applied to a valid entity, the modified entity will also be valid.
 * This method...
 * (1) Checks that required/ReadOnly/CreateOnly fields are not deleted.
 * (2) Checks that new values for record templates contain all required fields (treating ReadOnly fields as optional).
 * (3) Applies the patch to an empty entity and validates the entity for custom validation rules
 *     and Rest.li annotations, allowing the following exceptions:
 *     - Allows required fields to be absent by using {@link RequiredMode#IGNORE},
 *       because a patch does not necessarily contain all fields.
 *     - Allows array-descendant ReadOnly/CreateOnly fields to be set, since there's currently no way to "patch" arrays.
 *
 * @param patchRequest the patch
 * @return the final validation result
 */
private ValidationResult validatePatch(PatchRequest<?> patchRequest) {
    // Instantiate an empty entity.
    RecordTemplate entity;
    try {
        entity = _valueClass.newInstance();
    } catch (InstantiationException e) {
        return validationResultWithErrorMessage(INSTANTIATION_ERROR);
    } catch (IllegalAccessException e) {
        return validationResultWithErrorMessage(ILLEGAL_ACCESS_ERROR);
    }
    // Apply the patch to the entity and get paths that $set and $delete operations were performed on.
    @SuppressWarnings("unchecked") PatchRequest<RecordTemplate> patch = (PatchRequest<RecordTemplate>) patchRequest;
    DataComplexProcessor processor = new DataComplexProcessor(new Patch(true), patch.getPatchDocument(), entity.data());
    MessageList<Message> messages;
    try {
        messages = processor.runDataProcessing(false);
    } catch (DataProcessingException e) {
        return validationResultWithErrorMessage("Error while applying patch: " + e.getMessage());
    }
    // Check that required/ReadOnly/CreateOnly fields are not deleted
    ValidationErrorResult checkDeleteResult = new ValidationErrorResult();
    checkDeletesAreValid(entity.schema(), messages, checkDeleteResult);
    if (!checkDeleteResult.isValid()) {
        return checkDeleteResult;
    }
    // Check that new values for record templates contain all required fields
    ValidationResult checkSetResult = checkNewRecordsAreNotMissingFields(entity, messages);
    if (checkSetResult != null) {
        return checkSetResult;
    }
    // It's okay if required fields are absent in a partial update request, so use ignore mode.
    return ValidateDataAgainstSchema.validate(new SimpleDataElement(entity.data(), entity.schema()), new ValidationOptions(RequiredMode.IGNORE), getValidatorForInputEntityValidation(entity.schema()));
}
Also used : Message(com.linkedin.data.message.Message) PatchRequest(com.linkedin.restli.common.PatchRequest) DataComplexProcessor(com.linkedin.data.transform.DataComplexProcessor) ValidationResult(com.linkedin.data.schema.validation.ValidationResult) ValidationOptions(com.linkedin.data.schema.validation.ValidationOptions) DataProcessingException(com.linkedin.data.transform.DataProcessingException) RecordTemplate(com.linkedin.data.template.RecordTemplate) SimpleDataElement(com.linkedin.data.element.SimpleDataElement) Patch(com.linkedin.data.transform.patch.Patch)

Example 3 with PatchRequest

use of com.linkedin.restli.common.PatchRequest in project rest.li by linkedin.

the class ComplexKeysDataProvider method batchUpdate.

public BatchUpdateResult<ComplexResourceKey<TwoPartKey, TwoPartKey>, Message> batchUpdate(BatchPatchRequest<ComplexResourceKey<TwoPartKey, TwoPartKey>, Message> patches) {
    final Map<ComplexResourceKey<TwoPartKey, TwoPartKey>, UpdateResponse> results = new HashMap<>();
    for (Map.Entry<ComplexResourceKey<TwoPartKey, TwoPartKey>, PatchRequest<Message>> patch : patches.getData().entrySet()) {
        try {
            this.partialUpdate(patch.getKey(), patch.getValue());
            results.put(patch.getKey(), new UpdateResponse(HttpStatus.S_204_NO_CONTENT));
        } catch (DataProcessingException e) {
            results.put(patch.getKey(), new UpdateResponse(HttpStatus.S_400_BAD_REQUEST));
        }
    }
    return new BatchUpdateResult<>(results);
}
Also used : UpdateResponse(com.linkedin.restli.server.UpdateResponse) BatchUpdateResult(com.linkedin.restli.server.BatchUpdateResult) HashMap(java.util.HashMap) ComplexResourceKey(com.linkedin.restli.common.ComplexResourceKey) PatchRequest(com.linkedin.restli.common.PatchRequest) BatchPatchRequest(com.linkedin.restli.server.BatchPatchRequest) HashMap(java.util.HashMap) Map(java.util.Map) DataProcessingException(com.linkedin.data.transform.DataProcessingException)

Example 4 with PatchRequest

use of com.linkedin.restli.common.PatchRequest in project rest.li by linkedin.

the class AutomaticValidationDemoResource method batchUpdate.

@RestMethod.BatchPartialUpdate
public BatchUpdateResult<Integer, ValidationDemo> batchUpdate(final BatchPatchRequest<Integer, ValidationDemo> entityUpdates) {
    Map<Integer, UpdateResponse> results = new HashMap<>();
    Map<Integer, RestLiServiceException> errors = new HashMap<>();
    for (Map.Entry<Integer, PatchRequest<ValidationDemo>> entry : entityUpdates.getData().entrySet()) {
        Integer key = entry.getKey();
        PatchRequest<ValidationDemo> patch = entry.getValue();
        results.put(key, new UpdateResponse(HttpStatus.S_204_NO_CONTENT));
    }
    return new BatchUpdateResult<>(results, errors);
}
Also used : UpdateResponse(com.linkedin.restli.server.UpdateResponse) RestLiServiceException(com.linkedin.restli.server.RestLiServiceException) BatchUpdateResult(com.linkedin.restli.server.BatchUpdateResult) HashMap(java.util.HashMap) PatchRequest(com.linkedin.restli.common.PatchRequest) BatchPatchRequest(com.linkedin.restli.server.BatchPatchRequest) HashMap(java.util.HashMap) Map(java.util.Map) ValidationDemo(com.linkedin.restli.examples.greetings.api.ValidationDemo)

Example 5 with PatchRequest

use of com.linkedin.restli.common.PatchRequest in project rest.li by linkedin.

the class TestRestLiScatterGather method testSendScatterGatherRequest.

@Test(dataProvider = TestConstants.RESTLI_PROTOCOL_1_2_PREFIX + "scatterGatherDataProvider", // Known to be flaky in CI
retryAnalyzer = SingleRetry.class)
public static void testSendScatterGatherRequest(URIMapper mapper, RootBuilderWrapper<Long, Greeting> builders) throws RemoteInvocationException {
    RestLiClientConfig config = new RestLiClientConfig();
    config.setScatterGatherStrategy(new DefaultScatterGatherStrategy(mapper));
    RestClient restClient = new AlwaysD2RestClient(CLIENT, URI_PREFIX, config);
    final int NUM_IDS = 20;
    List<Greeting> entities = generateCreate(NUM_IDS);
    Long[] requestIds = prepareData(restClient, entities);
    // BATCH_GET
    testSendSGGetRequests(restClient, requestIds);
    testSendSGGetEntityRequests(restClient, requestIds);
    testSendSGGetKVRequests(restClient, requestIds);
    // BATCH_UPDATE
    Map<Long, Greeting> input = generateUpdates(requestIds);
    testSendSGUpdateRequests(restClient, input, builders);
    // BATCH_PATIAL_UPDATE
    Map<Long, PatchRequest<Greeting>> patch = generatePartialUpdates(requestIds);
    testSendSGPartialUpdateRequests(restClient, patch, builders);
    // BATCH_DELETE
    testSendSGDeleteRequests(restClient, requestIds, builders);
}
Also used : Greeting(com.linkedin.restli.examples.greetings.api.Greeting) RestLiClientConfig(com.linkedin.restli.client.util.RestLiClientConfig) PatchRequest(com.linkedin.restli.common.PatchRequest) RestLiIntegrationTest(com.linkedin.restli.examples.RestLiIntegrationTest) Test(org.testng.annotations.Test)

Aggregations

PatchRequest (com.linkedin.restli.common.PatchRequest)32 HashMap (java.util.HashMap)26 Test (org.testng.annotations.Test)22 Map (java.util.Map)14 Greeting (com.linkedin.restli.examples.greetings.api.Greeting)11 DataMap (com.linkedin.data.DataMap)9 BatchKVResponse (com.linkedin.restli.client.response.BatchKVResponse)8 UpdateStatus (com.linkedin.restli.common.UpdateStatus)6 BatchPatchRequest (com.linkedin.restli.server.BatchPatchRequest)6 ComplexResourceKey (com.linkedin.restli.common.ComplexResourceKey)5 CompoundKey (com.linkedin.restli.common.CompoundKey)5 CustomLong (com.linkedin.restli.examples.custom.types.CustomLong)5 CreateGreeting (com.linkedin.restli.examples.greetings.client.CreateGreeting)5 PartialUpdateGreeting (com.linkedin.restli.examples.greetings.client.PartialUpdateGreeting)5 PartialUpdateGreetingFluentClient (com.linkedin.restli.examples.greetings.client.PartialUpdateGreetingFluentClient)5 ValidationResult (com.linkedin.data.schema.validation.ValidationResult)4 StringMap (com.linkedin.data.template.StringMap)4 KeyValueRecord (com.linkedin.restli.common.KeyValueRecord)4 BatchUpdateResult (com.linkedin.restli.server.BatchUpdateResult)4 RestLiServiceException (com.linkedin.restli.server.RestLiServiceException)4