in repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java [507:649]
public AtlasSearchResult searchRelatedEntities(String guid, String relation, boolean getApproximateCount, SearchParameters searchParameters) throws AtlasBaseException {
AtlasSearchResult ret = new AtlasSearchResult(AtlasQueryType.RELATIONSHIP);
if (StringUtils.isEmpty(guid) || StringUtils.isEmpty(relation)) {
throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "guid: '" + guid + "', relation: '" + relation + "'");
}
//validate entity
AtlasVertex entityVertex = entityRetriever.getEntityVertex(guid);
String entityTypeName = GraphHelper.getTypeName(entityVertex);
AtlasEntityType entityType = typeRegistry.getEntityTypeByName(entityTypeName);
if (entityType == null) {
throw new AtlasBaseException(AtlasErrorCode.INVALID_RELATIONSHIP_TYPE, entityTypeName, guid);
}
//validate relation
AtlasEntityType endEntityType = null;
AtlasAttribute attribute = entityType.getAttribute(relation);
if (attribute == null) {
attribute = entityType.getRelationshipAttribute(relation, null);
}
if (attribute != null) {
//get end entity type through relationship attribute
endEntityType = attribute.getReferencedEntityType(typeRegistry);
if (endEntityType == null) {
throw new AtlasBaseException(AtlasErrorCode.INVALID_RELATIONSHIP_ATTRIBUTE, relation, attribute.getTypeName());
}
relation = attribute.getRelationshipEdgeLabel();
} else {
//get end entity type through label
String endEntityTypeName = GraphHelper.getReferencedEntityTypeName(entityVertex, relation);
if (StringUtils.isNotEmpty(endEntityTypeName)) {
endEntityType = typeRegistry.getEntityTypeByName(endEntityTypeName);
}
}
//validate sortBy attribute
String sortBy = searchParameters.getSortBy();
SortOrder sortOrder = searchParameters.getSortOrder();
int offset = searchParameters.getOffset();
int limit = searchParameters.getLimit();
String sortByAttributeName = DEFAULT_SORT_ATTRIBUTE_NAME;
if (StringUtils.isNotEmpty(sortBy)) {
sortByAttributeName = sortBy;
}
if (endEntityType != null) {
AtlasAttribute sortByAttribute = endEntityType.getAttribute(sortByAttributeName);
if (sortByAttribute == null) {
sortByAttributeName = null;
sortOrder = null;
if (StringUtils.isNotEmpty(sortBy)) {
LOG.info("Invalid sortBy Attribute {} for entityType {}, Ignoring Sorting", sortBy, endEntityType.getTypeName());
} else {
LOG.info("Invalid Default sortBy Attribute {} for entityType {}, Ignoring Sorting", DEFAULT_SORT_ATTRIBUTE_NAME, endEntityType.getTypeName());
}
} else {
sortByAttributeName = sortByAttribute.getVertexPropertyName();
if (sortOrder == null) {
sortOrder = ASCENDING;
}
}
} else {
sortOrder = null;
LOG.info("Invalid sortBy Attribute {}, Ignoring Sorting", sortBy);
}
//get relationship(end vertices) vertices
GraphTraversal gt = graph.V(entityVertex.getId()).bothE(relation).otherV();
if (searchParameters.getExcludeDeletedEntities()) {
gt.has(Constants.STATE_PROPERTY_KEY, AtlasEntity.Status.ACTIVE.name());
}
if (sortOrder != null) {
if (sortOrder == ASCENDING) {
gt.order().by(sortByAttributeName, Order.asc);
} else {
gt.order().by(sortByAttributeName, Order.desc);
}
}
gt.range(offset, offset + limit);
List<AtlasEntityHeader> resultList = new ArrayList<>();
while (gt.hasNext()) {
Vertex v = (Vertex) gt.next();
if (v != null && v.property(Constants.GUID_PROPERTY_KEY).isPresent()) {
String endVertexGuid = v.property(Constants.GUID_PROPERTY_KEY).value().toString();
AtlasVertex vertex = entityRetriever.getEntityVertex(endVertexGuid);
AtlasEntityHeader entity = entityRetriever.toAtlasEntityHeader(vertex, searchParameters.getAttributes());
if (searchParameters.getIncludeClassificationAttributes()) {
entity.setClassifications(entityRetriever.getAllClassifications(vertex));
}
resultList.add(entity);
}
}
ret.setEntities(resultList);
if (ret.getEntities() == null) {
ret.setEntities(new ArrayList<>());
}
//set approximate count
//state of the edge and endVertex will be same
if (getApproximateCount) {
Iterator<AtlasEdge> edges = GraphHelper.getAdjacentEdgesByLabel(entityVertex, AtlasEdgeDirection.BOTH, relation);
if (searchParameters.getExcludeDeletedEntities()) {
List<AtlasEdge> edgeList = new ArrayList<>();
edges.forEachRemaining(edgeList::add);
Predicate activePredicate = SearchPredicateUtil.getEQPredicateGenerator().generatePredicate(Constants.STATE_PROPERTY_KEY, AtlasEntity.Status.ACTIVE.name(), String.class);
CollectionUtils.filter(edgeList, activePredicate);
ret.setApproximateCount(edgeList.size());
} else {
ret.setApproximateCount(IteratorUtils.size(edges));
}
}
scrubSearchResults(ret);
return ret;
}