fix(gms): Validate unrecognized model fields. (#3034)

This commit is contained in:
John Joyce 2021-08-04 22:23:16 -07:00 committed by GitHub
parent 3d061161d8
commit 4649ca7f39
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 58 additions and 1 deletions

View File

@ -1,6 +1,9 @@
package com.linkedin.metadata.resources;
import com.linkedin.common.urn.UrnValidator;
import com.linkedin.data.schema.validation.CoercionMode;
import com.linkedin.data.schema.validation.RequiredMode;
import com.linkedin.data.schema.validation.UnrecognizedFieldMode;
import com.linkedin.data.schema.validation.ValidateDataAgainstSchema;
import com.linkedin.data.schema.validation.ValidationOptions;
import com.linkedin.data.schema.validation.ValidationResult;
@ -13,7 +16,11 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
public class ResourceUtils {
private static final ValidationOptions DEFAULT_VALIDATION_OPTIONS = new ValidationOptions();
private static final ValidationOptions DEFAULT_VALIDATION_OPTIONS = new ValidationOptions(
RequiredMode.CAN_BE_ABSENT_IF_HAS_DEFAULT,
CoercionMode.NORMAL,
UnrecognizedFieldMode.DISALLOW
);
private static final UrnValidator URN_VALIDATOR = new UrnValidator();
/**

View File

@ -0,0 +1,47 @@
package com.linkedin.metadata.resources;
import com.linkedin.common.BrowsePath;
import com.linkedin.common.Owner;
import com.linkedin.common.OwnershipType;
import com.linkedin.common.Status;
import com.linkedin.common.urn.Urn;
import com.linkedin.data.DataMap;
import com.linkedin.restli.common.HttpStatus;
import com.linkedin.restli.server.RestLiServiceException;
import org.testng.annotations.Test;
import org.testng.Assert;
public class ResourceUtilsTest {
@Test
public void testValidateOrThrowThrowsOnMissingUnrecognizedField() {
DataMap rawMap = new DataMap();
rawMap.put("removed", true);
rawMap.put("extraField", 1);
Status status = new Status(rawMap);
Assert.assertThrows(RestLiServiceException.class, () -> ResourceUtils.validateOrThrow(status, HttpStatus.S_500_INTERNAL_SERVER_ERROR));
}
@Test
public void testValidateOrThrowThrowsOnMissingRequiredField() {
DataMap rawMap = new DataMap();
BrowsePath status = new BrowsePath(rawMap);
Assert.assertThrows(RestLiServiceException.class, () -> ResourceUtils.validateOrThrow(status, HttpStatus.S_500_INTERNAL_SERVER_ERROR));
}
@Test
public void testValidateOrThrowDoesNotThrowOnMissingOptionalField() throws Exception {
DataMap rawMap = new DataMap();
Owner owner = new Owner(rawMap);
owner.setOwner(Urn.createFromString("urn:li:corpuser:test"));
owner.setType(OwnershipType.DATAOWNER);
ResourceUtils.validateOrThrow(owner, HttpStatus.S_500_INTERNAL_SERVER_ERROR);
}
@Test
public void testValidateOrThrowDoesNotThrowOnMissingDefaultField() {
DataMap rawMap = new DataMap();
Status status = new Status(rawMap);
ResourceUtils.validateOrThrow(status, HttpStatus.S_500_INTERNAL_SERVER_ERROR);
}
}

View File

@ -33,6 +33,9 @@ public class AspectExtractor {
final Map<String, DataElement> aspectsByName = new HashMap<>();
for (DataElement dataElement = iterator.next(); dataElement != null; dataElement = iterator.next()) {
if (dataElement.getSchemaPathSpec() == null) {
continue;
}
final PathSpec pathSpec = dataElement.getSchemaPathSpec();
List<String> pathComponents = pathSpec.getPathComponents();
// three components representing /aspect/*/<aspectClassName>