public AtlasSearchResult searchRelatedEntities()

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;
    }