org.apache.hugegraph.api.traversers.CustomizedCrosspointsAPI Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. The ASF
* licenses this file to You under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package org.apache.hugegraph.api.traversers;
import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_CAPACITY;
import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_MAX_DEGREE;
import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_PATHS_LIMIT;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.inject.Singleton;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.Context;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.apache.hugegraph.core.GraphManager;
import org.slf4j.Logger;
import org.apache.hugegraph.HugeGraph;
import org.apache.hugegraph.api.API;
import org.apache.hugegraph.backend.id.Id;
import org.apache.hugegraph.backend.query.QueryResults;
import org.apache.hugegraph.traversal.algorithm.CustomizedCrosspointsTraverser;
import org.apache.hugegraph.traversal.algorithm.HugeTraverser;
import org.apache.hugegraph.type.define.Directions;
import org.apache.hugegraph.util.E;
import org.apache.hugegraph.util.Log;
import com.codahale.metrics.annotation.Timed;
import com.fasterxml.jackson.annotation.JsonAlias;
import com.fasterxml.jackson.annotation.JsonProperty;
@Path("graphs/{graph}/traversers/customizedcrosspoints")
@Singleton
@Tag(name = "CustomizedCrosspointsAPI")
public class CustomizedCrosspointsAPI extends API {
private static final Logger LOG = Log.logger(CustomizedCrosspointsAPI.class);
@POST
@Timed
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON_WITH_CHARSET)
public String post(@Context GraphManager manager,
@PathParam("graph") String graph,
CrosspointsRequest request) {
E.checkArgumentNotNull(request,
"The crosspoints request body can't be null");
E.checkArgumentNotNull(request.sources,
"The sources of crosspoints request " +
"can't be null");
E.checkArgument(request.pathPatterns != null &&
!request.pathPatterns.isEmpty(),
"The steps of crosspoints request can't be empty");
LOG.debug("Graph [{}] get customized crosspoints from source vertex " +
"'{}', with path_pattern '{}', with_path '{}', with_vertex " +
"'{}', capacity '{}' and limit '{}'", graph, request.sources,
request.pathPatterns, request.withPath, request.withVertex,
request.capacity, request.limit);
HugeGraph g = graph(manager, graph);
Iterator sources = request.sources.vertices(g);
List patterns;
patterns = pathPatterns(g, request);
CustomizedCrosspointsTraverser traverser =
new CustomizedCrosspointsTraverser(g);
CustomizedCrosspointsTraverser.CrosspointsPaths paths;
paths = traverser.crosspointsPaths(sources, patterns, request.capacity,
request.limit);
Iterator iter = QueryResults.emptyIterator();
if (!request.withVertex) {
return manager.serializer(g).writeCrosspoints(paths, iter,
request.withPath);
}
Set ids = new HashSet<>();
if (request.withPath) {
for (HugeTraverser.Path p : paths.paths()) {
ids.addAll(p.vertices());
}
} else {
ids = paths.crosspoints();
}
if (!ids.isEmpty()) {
iter = g.vertices(ids.toArray());
}
return manager.serializer(g).writeCrosspoints(paths, iter,
request.withPath);
}
private static List
pathPatterns(HugeGraph graph, CrosspointsRequest request) {
int stepSize = request.pathPatterns.size();
List pathPatterns;
pathPatterns = new ArrayList<>(stepSize);
for (PathPattern pattern : request.pathPatterns) {
CustomizedCrosspointsTraverser.PathPattern pathPattern;
pathPattern = new CustomizedCrosspointsTraverser.PathPattern();
for (Step step : pattern.steps) {
pathPattern.add(step.jsonToStep(graph));
}
pathPatterns.add(pathPattern);
}
return pathPatterns;
}
private static class CrosspointsRequest {
@JsonProperty("sources")
public Vertices sources;
@JsonProperty("path_patterns")
public List pathPatterns;
@JsonProperty("capacity")
public long capacity = Long.parseLong(DEFAULT_CAPACITY);
@JsonProperty("limit")
public int limit = Integer.parseInt(DEFAULT_PATHS_LIMIT);
@JsonProperty("with_path")
public boolean withPath = false;
@JsonProperty("with_vertex")
public boolean withVertex = false;
@Override
public String toString() {
return String.format("CrosspointsRequest{sourceVertex=%s," +
"pathPatterns=%s,withPath=%s,withVertex=%s," +
"capacity=%s,limit=%s}", this.sources,
this.pathPatterns, this.withPath,
this.withVertex, this.capacity, this.limit);
}
}
private static class PathPattern {
@JsonProperty("steps")
public List steps;
@Override
public String toString() {
return String.format("PathPattern{steps=%s", this.steps);
}
}
private static class Step {
@JsonProperty("direction")
public Directions direction;
@JsonProperty("labels")
public List labels;
@JsonProperty("properties")
public Map properties;
@JsonAlias("degree")
@JsonProperty("max_degree")
public long maxDegree = Long.parseLong(DEFAULT_MAX_DEGREE);
@JsonProperty("skip_degree")
public long skipDegree = 0L;
@Override
public String toString() {
return String.format("Step{direction=%s,labels=%s,properties=%s," +
"maxDegree=%s,skipDegree=%s}",
this.direction, this.labels, this.properties,
this.maxDegree, this.skipDegree);
}
private CustomizedCrosspointsTraverser.Step jsonToStep(HugeGraph g) {
return new CustomizedCrosspointsTraverser.Step(g, this.direction,
this.labels,
this.properties,
this.maxDegree,
this.skipDegree);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy