Skip to content
Permalink
Browse files
hugegraph-889 async implementation of schema deletion and index rebuild
Change-Id: I94e6bb3b5e12097fbe3b7278df625b317137e38b
  • Loading branch information
zhoney authored and Linary committed Aug 9, 2018
1 parent 05700f2 commit 22c5b7762b1bb6decce6c959956ecfd910767264
Showing 62 changed files with 1,396 additions and 153 deletions.
@@ -5,7 +5,7 @@
<parent>
<artifactId>hugegraph</artifactId>
<groupId>com.baidu.hugegraph</groupId>
<version>0.7.2</version>
<version>0.7.3</version>
</parent>
<modelVersion>4.0.0</modelVersion>

@@ -103,7 +103,7 @@
</manifest>
<manifestEntries>
<Implementation-Version>
0.26.0.0
0.27.0.0
</Implementation-Version>
</manifestEntries>
</archive>
@@ -50,8 +50,9 @@ public void filter(ContainerRequestContext requestContext,
@NameBinding
@Retention(RetentionPolicy.RUNTIME)
public @interface Status {
final int OK = 200;
final int CREATED = 201;
int OK = 200;
int CREATED = 201;
int ACCEPTED = 202;

int value();
}
@@ -0,0 +1,163 @@
/*
* Copyright 2017 HugeGraph Authors
*
* 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 com.baidu.hugegraph.api.job;

import java.util.HashMap;
import java.util.Map;

import javax.inject.Singleton;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;

import org.slf4j.Logger;

import com.baidu.hugegraph.HugeGraph;
import com.baidu.hugegraph.api.API;
import com.baidu.hugegraph.api.filter.StatusFilter.Status;
import com.baidu.hugegraph.api.schema.Checkable;
import com.baidu.hugegraph.backend.id.Id;
import com.baidu.hugegraph.backend.query.Query;
import com.baidu.hugegraph.core.GraphManager;
import com.baidu.hugegraph.job.Job;
import com.baidu.hugegraph.job.JobBuilder;
import com.baidu.hugegraph.server.RestServer;
import com.baidu.hugegraph.traversal.optimize.HugeScriptTraversal;
import com.baidu.hugegraph.util.E;
import com.baidu.hugegraph.util.JsonUtil;
import com.baidu.hugegraph.util.Log;
import com.codahale.metrics.annotation.Timed;

import jersey.repackaged.com.google.common.collect.ImmutableMap;

@Path("graphs/{graph}/jobs/gremlin")
@Singleton
public class GremlinAPI extends API {

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

@POST
@Timed
@Status(Status.CREATED)
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON_WITH_CHARSET)
public Map<String, Id> post(@Context GraphManager manager,
@PathParam("graph") String graph,
GremlinRequest request) {
LOG.debug("Graph [{}] schedule gremlin job: {}", graph, request);
checkCreatingBody(request);

HugeGraph g = graph(manager, graph);
request.aliase(graph, "graph");
JobBuilder builder = JobBuilder.of(g).name(request.name())
.input(request.toJson())
.job(new GremlinJob());
return ImmutableMap.of("task_id", builder.schedule());
}

public static class GremlinJob extends Job<Object> {

public static final String TASK_TYPE = "gremlin";

@Override
public String type() {
return TASK_TYPE;
}

@Override
public Object call() throws Exception {
GremlinRequest input = GremlinRequest.fromJson(this.task().input());

HugeScriptTraversal<?, ?> st;
st = new HugeScriptTraversal<>(this.graph().traversal(),
input.language(), input.gremlin(),
input.bindings(), input.aliases());
long count = 0;
long capacity = Query.defaultCapacity(Query.NO_CAPACITY);
try {
while (st.hasNext()) {
st.next();
++count;
Thread.yield();
}
} finally {
Query.defaultCapacity(capacity);
st.close();
this.graph().tx().commit();
}

Object result = st.result();
return result != null ? result : count;
}
}

private static class GremlinRequest implements Checkable {

// See org.apache.tinkerpop.gremlin.server.channel.HttpChannelizer
public String gremlin;
public Map<String, Object> bindings = new HashMap<>();
public String language;
public Map<String, String> aliases = new HashMap<>();

public void aliase(String key, String value) {
this.aliases.put(key, value);
}

public Map<String, Object> bindings() {
return this.bindings;
}

public String language() {
return this.language;
}

public String gremlin() {
return this.gremlin;
}

public Map<String, String> aliases() {
return this.aliases;
}

public String name() {
// Get the first line of script as the name
return this.gremlin.split("\r\n|\r|\n", 2)[0];
}

@Override
public void checkCreate(boolean isBatch) {
E.checkArgumentNotNull(this.gremlin,
"The gremlin script can't be null");
E.checkArgument(this.aliases == null || this.aliases.isEmpty(),
"There is no need to pass gremlin aliases");
}

public String toJson() {
return JsonUtil.toJson(this);
}

public static GremlinRequest fromJson(String json) {
return JsonUtil.fromJson(json, GremlinRequest.class);
}
}
}
@@ -0,0 +1,96 @@
/*
* Copyright 2017 HugeGraph Authors
*
* 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 com.baidu.hugegraph.api.job;

import java.util.Map;

import javax.annotation.security.RolesAllowed;
import javax.inject.Singleton;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;

import org.slf4j.Logger;

import com.baidu.hugegraph.HugeGraph;
import com.baidu.hugegraph.api.API;
import com.baidu.hugegraph.api.filter.StatusFilter.Status;
import com.baidu.hugegraph.backend.id.Id;
import com.baidu.hugegraph.core.GraphManager;
import com.baidu.hugegraph.util.Log;
import com.codahale.metrics.annotation.Timed;
import com.google.common.collect.ImmutableMap;

@Path("graphs/{graph}/jobs/rebuild")
@Singleton
public class RebuildAPI extends API {

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

@PUT
@Timed
@Path("vertexlabels/{name}")
@Status(Status.ACCEPTED)
@Produces(APPLICATION_JSON_WITH_CHARSET)
@RolesAllowed({"admin", "$owner=graph"})
public Map<String, Id> vertexLabelRebuild(@Context GraphManager manager,
@PathParam("graph") String graph,
@PathParam("name") String name) {
LOG.debug("Graph [{}] rebuild vertex label: {}", graph, name);

HugeGraph g = graph(manager, graph);
return ImmutableMap.of("task_id",
g.schema().vertexLabel(name).rebuildIndex());
}

@PUT
@Timed
@Path("edgelabels/{name}")
@Status(Status.ACCEPTED)
@Produces(APPLICATION_JSON_WITH_CHARSET)
@RolesAllowed({"admin", "$owner=graph"})
public Map<String, Id> edgeLabelRebuild(@Context GraphManager manager,
@PathParam("graph") String graph,
@PathParam("name") String name) {
LOG.debug("Graph [{}] rebuild edge label: {}", graph, name);

HugeGraph g = graph(manager, graph);
return ImmutableMap.of("task_id",
g.schema().edgeLabel(name).rebuildIndex());
}

@PUT
@Timed
@Path("indexlabels/{name}")
@Status(Status.ACCEPTED)
@Produces(APPLICATION_JSON_WITH_CHARSET)
@RolesAllowed({"admin", "$owner=graph"})
public Map<String, Id> indexLabelRebuild(@Context GraphManager manager,
@PathParam("graph") String graph,
@PathParam("name") String name) {
LOG.debug("Graph [{}] rebuild index label: {}", graph, name);

HugeGraph g = graph(manager, graph);
return ImmutableMap.of("task_id",
g.schema().indexLabel(name).rebuild());
}
}

0 comments on commit 22c5b77

Please sign in to comment.