class FusiformSimilarityAPI extends API {

    private static final Logger LOG = Log.logger(FusiformSimilarityAPI.class);

    @POST
    @Timed
    @Consumes(APPLICATION_JSON)
    @Produces(APPLICATION_JSON_WITH_CHARSET)
    public String post(@Context GraphManager manager,
                       @PathParam("graph") String graph,
                       FusiformSimilarityRequest request) {<FILL_FUNCTION_BODY>}

    private static class FusiformSimilarityRequest {

        @JsonProperty("sources")
        public Vertices sources;
        @JsonProperty("label")
        public String label;
        @JsonProperty("direction")
        public Directions direction;
        @JsonProperty("min_neighbors")
        public int minNeighbors;
        @JsonProperty("alpha")
        public double alpha;
        @JsonProperty("min_similars")
        public int minSimilars = 1;
        @JsonProperty("top")
        public int top;
        @JsonProperty("group_property")
        public String groupProperty;
        @JsonProperty("min_groups")
        public int minGroups;
        @JsonProperty("max_degree")
        public long maxDegree = Long.parseLong(DEFAULT_MAX_DEGREE);
        @JsonProperty("capacity")
        public long capacity = Long.parseLong(DEFAULT_CAPACITY);
        @JsonProperty("limit")
        public int limit = Integer.parseInt(DEFAULT_PATHS_LIMIT);
        @JsonProperty("with_intermediary")
        public boolean withIntermediary = false;
        @JsonProperty("with_vertex")
        public boolean withVertex = false;

        @Override
        public String toString() {
            return String.format("FusiformSimilarityRequest{sources=%s," +
                                 "label=%s,direction=%s,minNeighbors=%s," +
                                 "alpha=%s,minSimilars=%s,top=%s," +
                                 "groupProperty=%s,minGroups=%s," +
                                 "maxDegree=%s,capacity=%s,limit=%s," +
                                 "withIntermediary=%s,withVertex=%s}",
                                 this.sources, this.label, this.direction,
                                 this.minNeighbors, this.alpha,
                                 this.minSimilars, this.top,
                                 this.groupProperty, this.minGroups,
                                 this.maxDegree, this.capacity, this.limit,
                                 this.withIntermediary, this.withVertex);
        }
    }
}

        E.checkArgumentNotNull(request, "The fusiform similarity " +
                                        "request body can't be null");
        E.checkArgumentNotNull(request.sources,
                               "The sources of fusiform similarity " +
                               "request can't be null");
        if (request.direction == null) {
            request.direction = Directions.BOTH;
        }
        E.checkArgument(request.minNeighbors > 0,
                        "The min neighbor count must be > 0, but got: %s",
                        request.minNeighbors);
        E.checkArgument(request.maxDegree > 0L || request.maxDegree == NO_LIMIT,
                        "The max degree of request must be > 0 or == -1, " +
                        "but got: %s", request.maxDegree);
        E.checkArgument(request.alpha > 0 && request.alpha <= 1.0,
                        "The alpha of request must be in range (0, 1], " +
                        "but got '%s'", request.alpha);
        E.checkArgument(request.minSimilars >= 1,
                        "The min similar count of request must be >= 1, " +
                        "but got: %s", request.minSimilars);
        E.checkArgument(request.top >= 0,
                        "The top must be >= 0, but got: %s", request.top);

        LOG.debug("Graph [{}] get fusiform similars from '{}' with " +
                  "direction '{}', edge label '{}', min neighbor count '{}', " +
                  "alpha '{}', min similar count '{}', group property '{}' " +
                  "and min group count '{}'",
                  graph, request.sources, request.direction, request.label,
                  request.minNeighbors, request.alpha, request.minSimilars,
                  request.groupProperty, request.minGroups);

        ApiMeasurer measure = new ApiMeasurer();
        HugeGraph g = graph(manager, graph);
        Iterator<Vertex> sources = request.sources.vertices(g);
        E.checkArgument(sources != null && sources.hasNext(),
                        "The source vertices can't be empty");

        FusiformSimilarityTraverser traverser = new FusiformSimilarityTraverser(g);
        SimilarsMap result = traverser.fusiformSimilarity(
                sources, request.direction, request.label,
                request.minNeighbors, request.alpha,
                request.minSimilars, request.top,
                request.groupProperty, request.minGroups,
                request.maxDegree, request.capacity,
                request.limit, request.withIntermediary);

        CloseableIterator.closeIterator(sources);

        measure.addIterCount(traverser.vertexIterCounter.get(),
                             traverser.edgeIterCounter.get());

        Iterator<?> iterVertex;
        Set<Id> vertexIds = result.vertices();
        if (request.withVertex && !vertexIds.isEmpty()) {
            iterVertex = g.vertices(vertexIds.toArray());
            measure.addIterCount(vertexIds.size(), 0);
        } else {
            iterVertex = vertexIds.iterator();
        }

        return manager.serializer(g, measure.measures())
                      .writeSimilars(result, iterVertex);
    
<methods>public non-sealed void <init>() ,public static boolean checkAndParseAction(java.lang.String) ,public static R commit(org.apache.hugegraph.HugeGraph, Callable<R>) ,public static void commit(org.apache.hugegraph.HugeGraph, java.lang.Runnable) ,public static org.apache.hugegraph.HugeGraph graph(org.apache.hugegraph.core.GraphManager, java.lang.String) ,public static org.apache.hugegraph.HugeGraph graph4admin(org.apache.hugegraph.core.GraphManager, java.lang.String) ,public static java.lang.Object[] properties(Map<java.lang.String,java.lang.Object>) <variables>public static final java.lang.String ACTION_APPEND,public static final java.lang.String ACTION_CLEAR,public static final java.lang.String ACTION_ELIMINATE,public static final java.lang.String APPLICATION_JSON,public static final java.lang.String APPLICATION_JSON_WITH_CHARSET,public static final java.lang.String APPLICATION_TEXT_WITH_CHARSET,public static final java.lang.String CHARSET,private static final Meter EXPECTED_ERROR_METER,private static final Meter ILLEGAL_ARG_ERROR_METER,public static final java.lang.String JSON,protected static final Logger LOG,private static final Meter SUCCEED_METER,public static final java.lang.String TEXT_PLAIN,private static final Meter UNKNOWN_ERROR_METER