Permalink
Browse files

Integration tests for projecting array fields with specific ranges.

RB=1153256
G=si-dev
R=kbalasub,mnchen
A=kbalasub,mnchen
  • Loading branch information...
saponniah committed Nov 9, 2017
1 parent 378277c commit 0f931a19598b709088e3d57a4f3318548db05cdd
Showing with 1,346 additions and 919 deletions.
  1. +8 −1 CHANGELOG
  2. +9 −9 data-transform/src/main/java/com/linkedin/data/transform/filter/MaskComposition.java
  3. +30 −0 data-transform/src/main/java/com/linkedin/data/transform/filter/request/MaskCreator.java
  4. +27 −0 data-transform/src/test/java/com/linkedin/data/transform/filter/TestMaskCreation.java
  5. +1 −1 gradle.properties
  6. +6 −0 restli-common/src/main/java/com/linkedin/restli/common/validation/RestLiDataValidator.java
  7. +9 −0 restli-int-test-api/src/main/pegasus/com/linkedin/restli/examples/greetings/api/Greeting.pdsc
  8. +6 −7 ...nt-test-api/src/main/snapshot/com.linkedin.restli.examples.greetings.client.actions.snapshot.json
  9. +6 −7 ...rc/main/snapshot/com.linkedin.restli.examples.greetings.client.annotatedComplexKeys.snapshot.json
  10. +6 −7 ...st-api/src/main/snapshot/com.linkedin.restli.examples.greetings.client.associations.snapshot.json
  11. +14 −7 ...est-api/src/main/snapshot/com.linkedin.restli.examples.greetings.client.asyncErrors.snapshot.json
  12. +62 −59 ...src/main/snapshot/com.linkedin.restli.examples.greetings.client.autoValidationDemos.snapshot.json
  13. +62 −59 ...snapshot/com.linkedin.restli.examples.greetings.client.autoValidationWithProjection.snapshot.json
  14. +14 −7 ...api/src/main/snapshot/com.linkedin.restli.examples.greetings.client.chainedTyperefs.snapshot.json
  15. +24 −17 ...st-api/src/main/snapshot/com.linkedin.restli.examples.greetings.client.complexArray.snapshot.json
  16. +50 −52 ...api/src/main/snapshot/com.linkedin.restli.examples.greetings.client.complexByteKeys.snapshot.json
  17. +6 −7 ...est-api/src/main/snapshot/com.linkedin.restli.examples.greetings.client.complexKeys.snapshot.json
  18. +14 −7 ...est-api/src/main/snapshot/com.linkedin.restli.examples.greetings.client.compression.snapshot.json
  19. +14 −7 ...int-test-api/src/main/snapshot/com.linkedin.restli.examples.greetings.client.cookie.snapshot.json
  20. +14 −7 ...-api/src/main/snapshot/com.linkedin.restli.examples.greetings.client.createGreeting.snapshot.json
  21. +14 −7 ...in/snapshot/com.linkedin.restli.examples.greetings.client.customMetadataProjections.snapshot.json
  22. +14 −7 ...est-api/src/main/snapshot/com.linkedin.restli.examples.greetings.client.customTypes.snapshot.json
  23. +14 −7 ...st-api/src/main/snapshot/com.linkedin.restli.examples.greetings.client.customTypes2.snapshot.json
  24. +19 −12 ...st-api/src/main/snapshot/com.linkedin.restli.examples.greetings.client.customTypes3.snapshot.json
  25. +14 −7 ...test-api/src/main/snapshot/com.linkedin.restli.examples.greetings.client.exceptions.snapshot.json
  26. +14 −7 ...est-api/src/main/snapshot/com.linkedin.restli.examples.greetings.client.exceptions2.snapshot.json
  27. +14 −7 ...est-api/src/main/snapshot/com.linkedin.restli.examples.greetings.client.exceptions3.snapshot.json
  28. +25 −19 ...nt-test-api/src/main/snapshot/com.linkedin.restli.examples.greetings.client.finders.snapshot.json
  29. +14 −7 ...t-test-api/src/main/snapshot/com.linkedin.restli.examples.greetings.client.greeting.snapshot.json
  30. +28 −22 ...-test-api/src/main/snapshot/com.linkedin.restli.examples.greetings.client.greetings.snapshot.json
  31. +14 −7 ...t-api/src/main/snapshot/com.linkedin.restli.examples.greetings.client.greetingsAuth.snapshot.json
  32. +28 −22 ...i/src/main/snapshot/com.linkedin.restli.examples.greetings.client.greetingsCallback.snapshot.json
  33. +28 −22 ...pi/src/main/snapshot/com.linkedin.restli.examples.greetings.client.greetingsPromise.snapshot.json
  34. +28 −22 ...src/main/snapshot/com.linkedin.restli.examples.greetings.client.greetingsPromiseCtx.snapshot.json
  35. +28 −22 ...t-api/src/main/snapshot/com.linkedin.restli.examples.greetings.client.greetingsTask.snapshot.json
  36. +14 −7 ...i/src/main/snapshot/com.linkedin.restli.examples.greetings.client.manualProjections.snapshot.json
  37. +14 −7 ...-int-test-api/src/main/snapshot/com.linkedin.restli.examples.greetings.client.mixed.snapshot.json
  38. +28 −22 ...st-api/src/main/snapshot/com.linkedin.restli.examples.greetings.client.nullGreeting.snapshot.json
  39. +17 −10 ...in/snapshot/com.linkedin.restli.examples.greetings.client.pagingMetadataProjections.snapshot.json
  40. +14 −7 .../src/main/snapshot/com.linkedin.restli.examples.greetings.client.streamingGreetings.snapshot.json
  41. +6 −7 ...test-api/src/main/snapshot/com.linkedin.restli.examples.greetings.client.stringKeys.snapshot.json
  42. +6 −7 ...linkedin.restli.examples.greetings.client.typerefCustomDoubleAssociationKeyResource.snapshot.json
  43. +14 −7 ...est-api/src/main/snapshot/com.linkedin.restli.examples.greetings.client.typerefKeys.snapshot.json
  44. +6 −7 ...inkedin.restli.examples.greetings.client.typerefPrimitiveLongAssociationKeyResource.snapshot.json
  45. +62 −59 ...api/src/main/snapshot/com.linkedin.restli.examples.greetings.client.validationDemos.snapshot.json
  46. +14 −7 ...est-api/src/main/snapshot/com.linkedin.restli.examples.greetings.client.withContext.snapshot.json
  47. +12 −14 ...t-api/src/main/snapshot/com.linkedin.restli.examples.groups.client.groupMemberships.snapshot.json
  48. +31 −35 ...rc/main/snapshot/com.linkedin.restli.examples.groups.client.groupMembershipsComplex.snapshot.json
  49. +181 −191 ...li-int-test-api/src/main/snapshot/com.linkedin.restli.examples.groups.client.groups.snapshot.json
  50. +14 −7 ...test-api/src/main/snapshot/com.linkedin.restli.examples.scala.client.scalaGreetings.snapshot.json
  51. +53 −55 ...-int-test-api/src/main/snapshot/com.linkedin.restli.examples.typeref.client.typeref.snapshot.json
  52. +14 −7 restli-int-test-api/src/main/snapshot/noNamespace.snapshot.json
  53. +10 −5 ...est-server/src/main/java/com/linkedin/restli/examples/greetings/server/GreetingsResourceImpl.java
  54. +154 −0 restli-int-test/src/test/java/com/linkedin/restli/examples/TestGreetingsClient.java
  55. +4 −0 restli-int-test/src/test/java/com/linkedin/restli/examples/TestResLiValidationWithProjection.java
View
@@ -1,13 +1,20 @@
16.0.6
------
16.0.5
------
(RB=1153256)
Integration tests for projecting array fields with specific ranges.
(RB=1155706)
Fix the DataTemplate generation issue on Gradle 4.3's modified OutputDirectory generation time.
16.0.4
------
(RB=1147537)
Logs request path only instead of the full URI
(RB=1154436)
Allows SslSessionNotTrustedException to be created with an inner exception and message
@@ -233,7 +233,6 @@ protected void storeNonDefaultValue(DataMap data, String tag, final Integer defa
data.remove(tag);
else
data.put(tag, value);
}
/**
@@ -313,7 +312,7 @@ boolean mergeWith1(DataMap mask, DataMap parent, String key)
* Removes array ranges from mask.
* @param data
*/
private void removeArrayRenges(DataMap data)
private void removeArrayRanges(DataMap data)
{
data.remove(FilterConstants.START);
data.remove(FilterConstants.COUNT);
@@ -336,8 +335,8 @@ private boolean composeField(final String fieldName,
{
instrCtx.setCurrentField(fieldName);
boolean failed = false;
if (dataMask == null)
boolean failed = false;
if (dataMask == null)
{
// avoid copying 1 if there exist wildcard with value 1
if (!opMask.equals(FilterConstants.POSITIVE) || !isMarkedAsMergedWith1(data))
@@ -348,7 +347,7 @@ else if (dataMask instanceof Integer)
{
//if mask is negative, then there is no need for further merging
//if it is positive, then
if (((Integer)dataMask).equals(FilterConstants.POSITIVE))
if (dataMask.equals(FilterConstants.POSITIVE))
{
if (opMask instanceof Integer)
{
@@ -393,11 +392,12 @@ else if (opMask.getClass() == DataMap.class)
instrCtx.addErrorMessage("field mask value of unsupported type: %1$s", opMask.getClass().getName());
failed = true;
}
} else
{
}
else
{
instrCtx.addErrorMessage("field mask value of unsupported type: %1$s", dataMask.getClass().getName());
failed = true;
}
}
//return true if operation was successful and false otherwise
return !failed;
@@ -431,7 +431,7 @@ private Integer merge(Integer m1, Integer m2, InterpreterContext instrCtx)
*/
private void prunePositiveMask(final DataMap complex)
{
removeArrayRenges(complex);
removeArrayRanges(complex);
final List<String> toBeRemoved = new ArrayList<String>();
for (Entry<String, Object> entry : complex.entrySet())
{
@@ -20,10 +20,13 @@
package com.linkedin.data.transform.filter.request;
import com.linkedin.data.DataMap;
import com.linkedin.data.schema.PathSpec;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
/**
* @author Josh Walker
@@ -83,6 +86,33 @@ private static MaskTree createMaskTree(Collection<PathSpec> paths, MaskOperation
{
maskTree.addOperation(path, op);
}
// Clean up empty masks. This usually happens for array masks whose $start and $count are removed if they have the
// default values of 0 and Integer.MAX_INT, respectively.
cleanUpEmptyMasks(maskTree.getDataMap());
return maskTree;
}
/**
* Helper method to clean up empty masks with positive integer mask
*/
private static void cleanUpEmptyMasks(DataMap mask)
{
for (Map.Entry<String, Object> entry: mask.entrySet())
{
if (entry.getValue() instanceof DataMap)
{
if (((DataMap) entry.getValue()).size() == 0)
{
// Replace the empty mask with positive integer mask
mask.put(entry.getKey(), MaskOperation.POSITIVE_MASK_OP.getRepresentation());
}
else
{
cleanUpEmptyMasks((DataMap) entry.getValue());
}
}
}
}
}
@@ -170,6 +170,33 @@ public void testPositiveMaskWithRandomAttributes()
Assert.assertEquals(mask.getDataMap(), expectedMaskMap);
}
@Test
public void testPositiveMaskWithFullArrayRangeValues()
{
PathSpec parentPath = new PathSpec("parent");
// Build the array field's path with range (0 to 999)
PathSpec arrayFirstHalfPath = new PathSpec(parentPath.getPathComponents(), "arrayField");
arrayFirstHalfPath.setAttribute(PathSpec.ATTR_ARRAY_START, 0);
arrayFirstHalfPath.setAttribute(PathSpec.ATTR_ARRAY_COUNT, 1000);
// Build the array field's path with range (1000 to Integer.MAX_INT)
PathSpec arraySecondHalfPath = new PathSpec(parentPath.getPathComponents(), "arrayField");
arraySecondHalfPath.setAttribute(PathSpec.ATTR_ARRAY_START, 1000);
arraySecondHalfPath.setAttribute(PathSpec.ATTR_ARRAY_COUNT, Integer.MAX_VALUE);
MaskTree mask = MaskCreator.createPositiveMask(arrayFirstHalfPath, arraySecondHalfPath);
// Build the expected map with both start and count filtered out
// {parent={arrayField=1}}
DataMap parentMap = new DataMap();
parentMap.put("arrayField", MaskOperation.POSITIVE_MASK_OP.getRepresentation());
DataMap expectedMaskMap = new DataMap();
expectedMaskMap.put("parent", parentMap);
Assert.assertEquals(mask.getDataMap(), expectedMaskMap);
}
@Test
public void testNegativeMaskSingleField()
{
View
@@ -1,4 +1,4 @@
version=16.0.4
version=16.0.5
sonatypeUsername=please_set_in_home_dir_if_uploading_to_maven_central
sonatypePassword=please_set_in_home_dir_if_uploading_to_maven_central
org.gradle.configureondemand=true
@@ -17,6 +17,7 @@
package com.linkedin.restli.common.validation;
import com.google.common.collect.Sets;
import com.linkedin.data.DataMap;
import com.linkedin.data.element.DataElement;
import com.linkedin.data.element.DataElementUtil;
@@ -130,6 +131,8 @@
private static final String ILLEGAL_ACCESS_ERROR = "IllegalAccessException while trying to instantiate the record template class";
private static final String TEMPLATE_RUNTIME_ERROR = "TemplateRuntimeException while trying to find the schema class";
private static final Set<String> ARRAY_RANGE_PARAMS = Sets.newHashSet(FilterConstants.START, FilterConstants.COUNT);
private static PathMatchesPatternPredicate stringToPredicate(String path, boolean includeDescendants)
{
// Discard the initial / character if present
@@ -659,6 +662,9 @@ private static ArrayDataSchema buildArrayDataSchemaByProjection(ArrayDataSchema
newSchema.setProperties(originalSchema.getProperties());
}
return newSchema;
} else if (ARRAY_RANGE_PARAMS.containsAll(maskMap.keySet())) {
// If the mask contains array range parameters without a WILDCARD, return the original schema
return originalSchema;
}
throw new IllegalArgumentException("Missing wildcard key in projection mask: " + maskMap.keySet());
@@ -16,6 +16,15 @@
"name" : "tone",
"doc" : "tone",
"type" : "Tone"
},
{
"name": "senders",
"doc": "Sender(s) of the message",
"type": {
"type": "array",
"items": "string"
},
"optional": true
}
]
}
@@ -1,10 +1,5 @@
{
"models" : [ {
"type" : "enum",
"name" : "Tone",
"namespace" : "com.linkedin.restli.examples.greetings.api",
"symbols" : [ "FRIENDLY", "SINCERE", "INSULTING" ]
}, {
"type" : "record",
"name" : "Message",
"namespace" : "com.linkedin.restli.examples.greetings.api",
@@ -17,10 +12,14 @@
"type" : "string"
}, {
"name" : "tone",
"type" : "Tone",
"type" : {
"type" : "enum",
"name" : "Tone",
"symbols" : [ "FRIENDLY", "SINCERE", "INSULTING" ]
},
"doc" : "tone"
} ]
} ],
}, "com.linkedin.restli.examples.greetings.api.Tone" ],
"schema" : {
"name" : "actions",
"namespace" : "com.linkedin.restli.examples.greetings.client",
@@ -1,10 +1,5 @@
{
"models" : [ {
"type" : "enum",
"name" : "Tone",
"namespace" : "com.linkedin.restli.examples.greetings.api",
"symbols" : [ "FRIENDLY", "SINCERE", "INSULTING" ]
}, {
"type" : "record",
"name" : "Message",
"namespace" : "com.linkedin.restli.examples.greetings.api",
@@ -17,10 +12,14 @@
"type" : "string"
}, {
"name" : "tone",
"type" : "Tone",
"type" : {
"type" : "enum",
"name" : "Tone",
"symbols" : [ "FRIENDLY", "SINCERE", "INSULTING" ]
},
"doc" : "tone"
} ]
}, {
}, "com.linkedin.restli.examples.greetings.api.Tone", {
"type" : "record",
"name" : "TwoPartKey",
"namespace" : "com.linkedin.restli.examples.greetings.api",
@@ -1,10 +1,5 @@
{
"models" : [ {
"type" : "enum",
"name" : "Tone",
"namespace" : "com.linkedin.restli.examples.greetings.api",
"symbols" : [ "FRIENDLY", "SINCERE", "INSULTING" ]
}, {
"type" : "record",
"name" : "Message",
"namespace" : "com.linkedin.restli.examples.greetings.api",
@@ -17,10 +12,14 @@
"type" : "string"
}, {
"name" : "tone",
"type" : "Tone",
"type" : {
"type" : "enum",
"name" : "Tone",
"symbols" : [ "FRIENDLY", "SINCERE", "INSULTING" ]
},
"doc" : "tone"
} ]
} ],
}, "com.linkedin.restli.examples.greetings.api.Tone" ],
"schema" : {
"name" : "associations",
"namespace" : "com.linkedin.restli.examples.greetings.client",
@@ -1,10 +1,5 @@
{
"models" : [ {
"type" : "enum",
"name" : "Tone",
"namespace" : "com.linkedin.restli.examples.greetings.api",
"symbols" : [ "FRIENDLY", "SINCERE", "INSULTING" ]
}, {
"type" : "record",
"name" : "Greeting",
"namespace" : "com.linkedin.restli.examples.greetings.api",
@@ -17,10 +12,22 @@
"type" : "string"
}, {
"name" : "tone",
"type" : "Tone",
"type" : {
"type" : "enum",
"name" : "Tone",
"symbols" : [ "FRIENDLY", "SINCERE", "INSULTING" ]
},
"doc" : "tone"
}, {
"name" : "senders",
"type" : {
"type" : "array",
"items" : "string"
},
"doc" : "Sender(s) of the message",
"optional" : true
} ]
} ],
}, "com.linkedin.restli.examples.greetings.api.Tone" ],
"schema" : {
"name" : "asyncErrors",
"namespace" : "com.linkedin.restli.examples.greetings.client",
Oops, something went wrong.

0 comments on commit 0f931a1

Please sign in to comment.