Skip to content

Commit

Permalink
refactor(dao): Move createRelationshipFilter from Neo4jUtil to QueryU…
Browse files Browse the repository at this point in the history
…tils (#121)
  • Loading branch information
EnricoMi authored Sep 7, 2021
1 parent e91d1c3 commit e003c30
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
import com.linkedin.metadata.query.Criterion;
import com.linkedin.metadata.query.CriterionArray;
import com.linkedin.metadata.query.Filter;
import com.linkedin.metadata.query.RelationshipDirection;
import com.linkedin.metadata.query.RelationshipFilter;

import java.util.Collections;
import java.util.Map;
import java.util.Objects;
Expand Down Expand Up @@ -56,6 +59,34 @@ public static Filter newFilter(@Nonnull String field, @Nonnull String value) {
return newFilter(Collections.singletonMap(field, value));
}


/**
* Create {@link RelationshipFilter} using filter and relationship direction.
*
* @param filter {@link Filter} filter
* @param relationshipDirection {@link RelationshipDirection} relationship direction
* @return RelationshipFilter
*/
@Nonnull
public static RelationshipFilter newRelationshipFilter(@Nonnull Filter filter,
@Nonnull RelationshipDirection relationshipDirection) {
return new RelationshipFilter().setCriteria(filter.getCriteria()).setDirection(relationshipDirection);
}

/**
* Create {@link RelationshipFilter} using filter conditions and relationship direction.
*
* @param field field to create a filter on
* @param value field value to be filtered
* @param relationshipDirection {@link RelationshipDirection} relationship direction
* @return RelationshipFilter
*/
@Nonnull
public static RelationshipFilter newRelationshipFilter(@Nonnull String field, @Nonnull String value,
@Nonnull RelationshipDirection relationshipDirection) {
return newRelationshipFilter(newFilter(field, value), relationshipDirection);
}

/**
* Converts a set of aspect classes to a set of {@link AspectVersion} with the version all set to latest.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,18 @@
import com.linkedin.metadata.aspect.AspectVersion;
import com.linkedin.metadata.query.Condition;
import com.linkedin.metadata.query.Criterion;
import com.linkedin.metadata.query.CriterionArray;
import com.linkedin.metadata.query.Filter;
import com.linkedin.metadata.query.RelationshipDirection;
import com.linkedin.metadata.query.RelationshipFilter;
import com.linkedin.testing.AspectBar;
import com.linkedin.testing.AspectFoo;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import org.testng.annotations.Test;

import static com.linkedin.metadata.dao.utils.QueryUtils.newRelationshipFilter;
import static org.testng.Assert.*;


Expand All @@ -39,6 +43,19 @@ public void testNewFilter() {
assertEquals(filter.getCriteria().size(), 0);
}

@Test
public void testNewRelationshipFilter() {
String field = "field";
String value = "value";
RelationshipDirection direction = RelationshipDirection.OUTGOING;

RelationshipFilter relationshipFilter = new RelationshipFilter().setCriteria(new CriterionArray(
Collections.singletonList(new Criterion().setField(field).setValue(value).setCondition(Condition.EQUAL))))
.setDirection(direction);

assertEquals(newRelationshipFilter(field, value, direction), relationshipFilter);
}

@Test
public void testLatestAspectVersions() {
Set<Class<? extends RecordTemplate>> aspects = ImmutableSet.of(AspectFoo.class, AspectBar.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,28 +251,32 @@ public static String getType(@Nonnull Class<? extends RecordTemplate> recordClas

/**
* Create {@link RelationshipFilter} using filter and relationship direction.
* @deprecated Use `newRelationshipFilter` in {@link com.linkedin.metadata.dao.utils.QueryUtils} instead.
*
* @param filter {@link Filter} filter
* @param relationshipDirection {@link RelationshipDirection} relationship direction
* @return RelationshipFilter
*/
@Nonnull
@Deprecated
public static RelationshipFilter createRelationshipFilter(@Nonnull Filter filter,
@Nonnull RelationshipDirection relationshipDirection) {
return new RelationshipFilter().setCriteria(filter.getCriteria()).setDirection(relationshipDirection);
return newRelationshipFilter(filter, relationshipDirection);
}

/**
* Create {@link RelationshipFilter} using filter conditions and relationship direction.
* @deprecated Use `newRelationshipFilter` in {@link com.linkedin.metadata.dao.utils.QueryUtils} instead.
*
* @param field field to create a filter on
* @param value field value to be filtered
* @param relationshipDirection {@link RelationshipDirection} relationship direction
* @return RelationshipFilter
*/
@Nonnull
@Deprecated
public static RelationshipFilter createRelationshipFilter(@Nonnull String field, @Nonnull String value,
@Nonnull RelationshipDirection relationshipDirection) {
return createRelationshipFilter(newFilter(field, value), relationshipDirection);
return newRelationshipFilter(field, value, relationshipDirection);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import static com.linkedin.metadata.dao.Neo4jUtil.*;
import static com.linkedin.metadata.dao.utils.QueryUtils.*;
import static com.linkedin.testing.TestUtils.*;
import static org.testng.Assert.*;
Expand Down Expand Up @@ -159,21 +158,21 @@ public void testFindEntityWithOneRelationship() throws Exception {
// use case: the direct reportee to me (urn2)
List<RecordTemplate> resultIncoming =
_dao.findEntities(EntityFoo.class, sourceFilter, EntityFoo.class, EMPTY_FILTER, RelationshipFoo.class,
createRelationshipFilter(EMPTY_FILTER, RelationshipDirection.INCOMING), 0, 10);
newRelationshipFilter(EMPTY_FILTER, RelationshipDirection.INCOMING), 0, 10);
assertEquals(resultIncoming.size(), 1);
assertEquals(resultIncoming.get(0), entity1);

// use case: the manager I (urn2) am report to
List<RecordTemplate> resultOutgoing =
_dao.findEntities(EntityFoo.class, sourceFilter, EntityFoo.class, EMPTY_FILTER, RelationshipFoo.class,
createRelationshipFilter(EMPTY_FILTER, RelationshipDirection.OUTGOING), 0, 10);
newRelationshipFilter(EMPTY_FILTER, RelationshipDirection.OUTGOING), 0, 10);
assertEquals(resultOutgoing.size(), 1);
assertEquals(resultOutgoing.get(0), entity3);

// use case: give me my friends at one degree/hop
List<RecordTemplate> resultUndirected =
_dao.findEntities(EntityFoo.class, sourceFilter, EntityFoo.class, EMPTY_FILTER, RelationshipFoo.class,
createRelationshipFilter(EMPTY_FILTER, RelationshipDirection.UNDIRECTED), 0, 10);
newRelationshipFilter(EMPTY_FILTER, RelationshipDirection.UNDIRECTED), 0, 10);
assertEquals(resultUndirected.size(), 2);
assertEquals(resultUndirected.get(0), entity1);
assertEquals(resultUndirected.get(1), entity3);
Expand All @@ -183,7 +182,7 @@ public void testFindEntityWithOneRelationship() throws Exception {
sourceFilter = newFilter("urn", urn1.toString());
List<RecordTemplate> resultNullDest =
_dao.findEntities(EntityFoo.class, sourceFilter, null, EMPTY_FILTER, RelationshipFoo.class,
createRelationshipFilter(EMPTY_FILTER, RelationshipDirection.OUTGOING), 0, 10);
newRelationshipFilter(EMPTY_FILTER, RelationshipDirection.OUTGOING), 0, 10);
assertEquals(resultNullDest.size(), 2);
assertEquals(resultNullDest.get(0), entity2);
assertEquals(resultNullDest.get(1), entity4);
Expand All @@ -192,22 +191,22 @@ public void testFindEntityWithOneRelationship() throws Exception {
sourceFilter = newFilter("value", "foo2");
List<RecordTemplate> result =
_dao.findEntities(EntityFoo.class, sourceFilter, EntityFoo.class, EMPTY_FILTER, RelationshipFoo.class,
createRelationshipFilter(EMPTY_FILTER, RelationshipDirection.INCOMING), 0, 10);
newRelationshipFilter(EMPTY_FILTER, RelationshipDirection.INCOMING), 0, 10);
assertEquals(result, resultIncoming);

//Test relationship filters on the attributes
Filter filter = newFilter("type", "apa");
List<RecordTemplate> resultWithRelationshipFilter =
_dao.findEntities(EntityFoo.class, sourceFilter, EntityFoo.class, EMPTY_FILTER, RelationshipFoo.class,
createRelationshipFilter(filter, RelationshipDirection.OUTGOING), 0, 10);
newRelationshipFilter(filter, RelationshipDirection.OUTGOING), 0, 10);
assertEquals(resultWithRelationshipFilter.size(), 1);
assertEquals(resultWithRelationshipFilter.get(0), entity3);

//Test a wrong value for relationship filters
Filter relationshipFilterWrongValue = newFilter("type", "wrongValue");
List<RecordTemplate> resultWithRelationshipFilter2 =
_dao.findEntities(EntityFoo.class, sourceFilter, EntityFoo.class, EMPTY_FILTER, RelationshipFoo.class,
createRelationshipFilter(relationshipFilterWrongValue, RelationshipDirection.OUTGOING), 0, 10);
newRelationshipFilter(relationshipFilterWrongValue, RelationshipDirection.OUTGOING), 0, 10);
assertEquals(resultWithRelationshipFilter2.size(), 0);
}

Expand Down Expand Up @@ -237,22 +236,22 @@ public void testFindEntitiesMultiHops() throws Exception {
Filter sourceFilter = newFilter("urn", urn1.toString());
List<RecordTemplate> result =
_dao.findEntities(EntityFoo.class, sourceFilter, EntityFoo.class, EMPTY_FILTER, RelationshipFoo.class,
createRelationshipFilter(EMPTY_FILTER, RelationshipDirection.OUTGOING), 1, 1, 0, 10);
newRelationshipFilter(EMPTY_FILTER, RelationshipDirection.OUTGOING), 1, 1, 0, 10);
assertEquals(result.size(), 1);
assertEquals(result.get(0), entity2);

// get result with 2 hops, two managers
List<RecordTemplate> result2 =
_dao.findEntities(EntityFoo.class, sourceFilter, EntityFoo.class, EMPTY_FILTER, RelationshipFoo.class,
createRelationshipFilter(EMPTY_FILTER, RelationshipDirection.OUTGOING), 1, 2, 0, 10);
newRelationshipFilter(EMPTY_FILTER, RelationshipDirection.OUTGOING), 1, 2, 0, 10);
assertEquals(result2.size(), 2);
assertEquals(result2.get(0), entity2);
assertEquals(result2.get(1), entity3);

// get result with >= 3 hops, until end of the chain
List<RecordTemplate> result3 =
_dao.findEntities(EntityFoo.class, sourceFilter, EntityFoo.class, EMPTY_FILTER, RelationshipFoo.class,
createRelationshipFilter(EMPTY_FILTER, RelationshipDirection.OUTGOING), 1, 3, 0, 10);
newRelationshipFilter(EMPTY_FILTER, RelationshipDirection.OUTGOING), 1, 3, 0, 10);
assertEquals(result3.size(), 2);
assertEquals(result3.get(0), entity2);
assertEquals(result3.get(1), entity3);
Expand All @@ -261,7 +260,7 @@ public void testFindEntitiesMultiHops() throws Exception {
Filter destFilter = newFilter("urn", urn3.toString());
List<RecordTemplate> result4 =
_dao.findEntities(EntityFoo.class, sourceFilter, EntityFoo.class, destFilter, RelationshipFoo.class,
createRelationshipFilter(EMPTY_FILTER, RelationshipDirection.OUTGOING), 1, 3, 0, 10);
newRelationshipFilter(EMPTY_FILTER, RelationshipDirection.OUTGOING), 1, 3, 0, 10);
assertEquals(result4.size(), 1);
assertEquals(result4.get(0), entity3);

Expand All @@ -270,13 +269,13 @@ public void testFindEntitiesMultiHops() throws Exception {
// corner cases 1: minHops set to 3, get no result because the relationship chain reaches the end
List<RecordTemplate> result5 =
_dao.findEntities(EntityFoo.class, sourceFilter, EntityFoo.class, EMPTY_FILTER, RelationshipFoo.class,
createRelationshipFilter(EMPTY_FILTER, RelationshipDirection.OUTGOING), 3, 6, 0, 10);
newRelationshipFilter(EMPTY_FILTER, RelationshipDirection.OUTGOING), 3, 6, 0, 10);
assertEquals(result5.size(), 0);

// corner cases 2: minHops < maxHops, return no result
List<RecordTemplate> result6 =
_dao.findEntities(EntityFoo.class, sourceFilter, EntityFoo.class, EMPTY_FILTER, RelationshipFoo.class,
createRelationshipFilter(EMPTY_FILTER, RelationshipDirection.OUTGOING), 6, 0, 0, 10);
newRelationshipFilter(EMPTY_FILTER, RelationshipDirection.OUTGOING), 6, 0, 0, 10);
assertEquals(result6.size(), 0);

// test the relationship directions
Expand All @@ -285,29 +284,29 @@ public void testFindEntitiesMultiHops() throws Exception {
Filter sourceFilter2 = newFilter("urn", urn2.toString());
List<RecordTemplate> result21 =
_dao.findEntities(EntityFoo.class, sourceFilter2, EntityFoo.class, EMPTY_FILTER, RelationshipFoo.class,
createRelationshipFilter(EMPTY_FILTER, RelationshipDirection.OUTGOING), 1, 1, 0, 10);
newRelationshipFilter(EMPTY_FILTER, RelationshipDirection.OUTGOING), 1, 1, 0, 10);
assertEquals(result21.size(), 1);
assertEquals(result21.get(0), entity3);

// get result with 2 hops, 1 manager
List<RecordTemplate> result22 =
_dao.findEntities(EntityFoo.class, sourceFilter2, EntityFoo.class, EMPTY_FILTER, RelationshipFoo.class,
createRelationshipFilter(EMPTY_FILTER, RelationshipDirection.OUTGOING), 1, 2, 0, 10);
newRelationshipFilter(EMPTY_FILTER, RelationshipDirection.OUTGOING), 1, 2, 0, 10);
assertEquals(result22.size(), 1);
assertEquals(result22.get(0), entity3);

// let's see what we get if we use interface 1, it should return urn3 only
List<RecordTemplate> resultInterface1 =
_dao.findEntities(EntityFoo.class, sourceFilter2, null, EMPTY_FILTER, RelationshipFoo.class,
createRelationshipFilter(EMPTY_FILTER, RelationshipDirection.OUTGOING), 0, 10);
newRelationshipFilter(EMPTY_FILTER, RelationshipDirection.OUTGOING), 0, 10);
assertEquals(resultInterface1.size(), 1);
assertEquals(resultInterface1.get(0), entity3);

// test INCOMING direction, use case such as who report to URN3
Filter sourceFilter3 = newFilter("urn", urn3.toString());
List<RecordTemplate> resultIncoming =
_dao.findEntities(EntityFoo.class, sourceFilter3, EntityFoo.class, EMPTY_FILTER, RelationshipFoo.class,
createRelationshipFilter(EMPTY_FILTER, RelationshipDirection.INCOMING), 1, 2, 0, 10);
newRelationshipFilter(EMPTY_FILTER, RelationshipDirection.INCOMING), 1, 2, 0, 10);
assertEquals(resultIncoming.size(), 2);
assertEquals(resultIncoming.get(0), entity2);
assertEquals(resultIncoming.get(1), entity1);
Expand Down Expand Up @@ -342,10 +341,10 @@ public void testFindEntitiesViaTraversePathes() throws Exception {
// use case: return all the datasets owned by corpgroup1
List paths = new ArrayList();
paths.add(
Triplet.with(RelationshipFoo.class, createRelationshipFilter(EMPTY_FILTER, RelationshipDirection.OUTGOING),
Triplet.with(RelationshipFoo.class, newRelationshipFilter(EMPTY_FILTER, RelationshipDirection.OUTGOING),
EntityBar.class));
paths.add(
Triplet.with(RelationshipBar.class, createRelationshipFilter(EMPTY_FILTER, RelationshipDirection.INCOMING),
Triplet.with(RelationshipBar.class, newRelationshipFilter(EMPTY_FILTER, RelationshipDirection.INCOMING),
EntityBaz.class));
List<RecordTemplate> result = _dao.findEntities(EntityFoo.class, sourceFilter, paths, 0, 10);
assertEquals(result.size(), 1);
Expand All @@ -354,10 +353,10 @@ public void testFindEntitiesViaTraversePathes() throws Exception {
// use case: return all the datasets owned by corpgroup1
List paths2 = new ArrayList();
paths2.add(
Triplet.with(RelationshipFoo.class, createRelationshipFilter(EMPTY_FILTER, RelationshipDirection.UNDIRECTED),
Triplet.with(RelationshipFoo.class, newRelationshipFilter(EMPTY_FILTER, RelationshipDirection.UNDIRECTED),
EntityBar.class));
paths2.add(
Triplet.with(RelationshipBar.class, createRelationshipFilter(EMPTY_FILTER, RelationshipDirection.UNDIRECTED),
Triplet.with(RelationshipBar.class, newRelationshipFilter(EMPTY_FILTER, RelationshipDirection.UNDIRECTED),
EntityBaz.class));
List<RecordTemplate> result2 = _dao.findEntities(EntityFoo.class, sourceFilter, paths2, 0, 10);
assertEquals(result2, result);
Expand All @@ -381,10 +380,10 @@ public void testFindEntitiesViaTraversePathes() throws Exception {

List paths3 = new ArrayList();
paths3.add(
Triplet.with(RelationshipFoo.class, createRelationshipFilter(EMPTY_FILTER, RelationshipDirection.OUTGOING),
Triplet.with(RelationshipFoo.class, newRelationshipFilter(EMPTY_FILTER, RelationshipDirection.OUTGOING),
EntityBar.class));
paths3.add(
Triplet.with(RelationshipBar.class, createRelationshipFilter(EMPTY_FILTER, RelationshipDirection.INCOMING),
Triplet.with(RelationshipBar.class, newRelationshipFilter(EMPTY_FILTER, RelationshipDirection.INCOMING),
EntityBaz.class));
List<RecordTemplate> result3 = _dao.findEntities(EntityFoo.class, sourceFilter, paths3, 0, 10);
assertEquals(result3.size(), 2);
Expand All @@ -402,7 +401,7 @@ public void testFindEntitiesViaTraversePathes() throws Exception {
// test partial nulls with entity
List paths5 = new ArrayList();
paths5.add(
Triplet.with(null, createRelationshipFilter(EMPTY_FILTER, RelationshipDirection.OUTGOING), EntityBar.class));
Triplet.with(null, newRelationshipFilter(EMPTY_FILTER, RelationshipDirection.OUTGOING), EntityBar.class));
List<RecordTemplate> result5 = _dao.findEntities(EntityFoo.class, sourceFilter, paths5, 0, 10);
assertEquals(result5.size(), 2);
assertEquals(result5.get(0), entity4);
Expand Down Expand Up @@ -510,7 +509,7 @@ public void testFindNodesInPath() throws Exception {

// Get reports roll-up - 2 levels
Filter sourceFilter = newFilter("urn", urn1.toString());
RelationshipFilter relationshipFilter = createRelationshipFilter(EMPTY_FILTER, RelationshipDirection.INCOMING);
RelationshipFilter relationshipFilter = newRelationshipFilter(EMPTY_FILTER, RelationshipDirection.INCOMING);
List<List<RecordTemplate>> paths = _dao.findPaths(EntityFoo.class, sourceFilter, null,
EMPTY_FILTER, RelationshipFoo.class, relationshipFilter, 1, 2, -1, -1);
assertEquals(paths.size(), 5);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
import com.linkedin.metadata.query.Criterion;
import com.linkedin.metadata.query.CriterionArray;
import com.linkedin.metadata.query.Filter;
import com.linkedin.metadata.query.RelationshipDirection;
import com.linkedin.metadata.query.RelationshipFilter;
import com.linkedin.testing.EntityBar;
import com.linkedin.testing.EntityFoo;
import com.linkedin.testing.RelationshipFoo;
Expand Down Expand Up @@ -178,19 +176,6 @@ public void testGetTypeOrEmptyString() {
assertEquals(getTypeOrEmptyString(null), "");
}

@Test
public void testCreateRelationshipFilter() {
String field = "field";
String value = "value";
RelationshipDirection direction = RelationshipDirection.OUTGOING;

RelationshipFilter relationshipFilter = new RelationshipFilter().setCriteria(new CriterionArray(
Collections.singletonList(new Criterion().setField(field).setValue(value).setCondition(Condition.EQUAL))))
.setDirection(direction);

assertEquals(createRelationshipFilter(field, value, direction), relationshipFilter);
}

@Test
public void testPathSegmentToRecordList() {
FooUrn fooUrn = makeFooUrn(1);
Expand Down

0 comments on commit e003c30

Please sign in to comment.