From 05669ed6b983cdfa1d3dd9a2aeb9893afdba568c Mon Sep 17 00:00:00 2001 From: zhangyi51 Date: Tue, 15 Jan 2019 17:47:32 +0800 Subject: [PATCH] fix bug of aysnc left index delete 1. use element id as task name 2. check whether element is already deleted 3. use async mode for HugeGraphServer Change-Id: Id8471712e2cd9b5f7cff4639b27e6c198e4d1f01 fixed: #247 --- .../backend/tx/GraphIndexTransaction.java | 5 +- .../baidu/hugegraph/structure/HugeVertex.java | 7 +- .../com/baidu/hugegraph/api/ApiTestSuite.java | 1 + .../com/baidu/hugegraph/api/BaseApiTest.java | 37 ++++++- .../com/baidu/hugegraph/api/TaskApiTest.java | 103 ++++++++++++++++++ 5 files changed, 147 insertions(+), 6 deletions(-) create mode 100644 hugegraph-test/src/main/java/com/baidu/hugegraph/api/TaskApiTest.java diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/tx/GraphIndexTransaction.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/tx/GraphIndexTransaction.java index d7daf54ff0..5a35c517d4 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/tx/GraphIndexTransaction.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/tx/GraphIndexTransaction.java @@ -91,7 +91,7 @@ protected Id asyncRemoveIndexLeft(ConditionQuery query, HugeElement element) { RemoveLeftIndexJob callable = new RemoveLeftIndexJob(query, element); HugeTask task = EphemeralJobBuilder.of(this.graph()) - .name(element.name()) + .name(element.id().asString()) .job(callable) .schedule(); return task.id(); @@ -1199,6 +1199,9 @@ private boolean deletedByError(HugeElement element, Collection ilFields, Map incorrectPKs) { HugeElement elem = this.newestElement(element); + if (elem == null) { + return false; + } for (Map.Entry e : incorrectPKs.entrySet()) { PropertyKey pk = e.getKey(); Object value = e.getValue(); diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/structure/HugeVertex.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/structure/HugeVertex.java index 348960b62a..4740494d29 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/structure/HugeVertex.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/structure/HugeVertex.java @@ -93,12 +93,15 @@ public VertexLabel schemaLabel() { @Override public String name() { - assert this.label.idStrategy() == IdStrategy.PRIMARY_KEY; + E.checkState(this.label.idStrategy() == IdStrategy.PRIMARY_KEY, + "Only primary key vertex has name, " + + "but got '%s' with id strategy '%s'", + this, this.label.idStrategy()); if (this.name == null) { if (this.id != null) { String[] parts = SplicingIdGenerator.parse(this.id); E.checkState(parts.length == 2, - "Invalid vertex id '%s'", this.id); + "Invalid primary key vertex id '%s'", this.id); this.name = parts[1]; } else { assert this.id == null; diff --git a/hugegraph-test/src/main/java/com/baidu/hugegraph/api/ApiTestSuite.java b/hugegraph-test/src/main/java/com/baidu/hugegraph/api/ApiTestSuite.java index fd6ffd34a0..af8fadda93 100644 --- a/hugegraph-test/src/main/java/com/baidu/hugegraph/api/ApiTestSuite.java +++ b/hugegraph-test/src/main/java/com/baidu/hugegraph/api/ApiTestSuite.java @@ -33,6 +33,7 @@ IndexLabelApiTest.class, VertexApiTest.class, EdgeApiTest.class, + TaskApiTest.class, GremlinApiTest.class, MetricsApiTest.class }) diff --git a/hugegraph-test/src/main/java/com/baidu/hugegraph/api/BaseApiTest.java b/hugegraph-test/src/main/java/com/baidu/hugegraph/api/BaseApiTest.java index 543eddbb52..377054e855 100644 --- a/hugegraph-test/src/main/java/com/baidu/hugegraph/api/BaseApiTest.java +++ b/hugegraph-test/src/main/java/com/baidu/hugegraph/api/BaseApiTest.java @@ -249,6 +249,20 @@ protected static void initEdgeLabel() { + "}"); } + protected static void initIndexLabel() { + String path = URL_PREFIX + SCHEMA_ILS; + + client.post(path, "{\n" + + "\"name\": \"personByCity\",\n" + + "\"base_type\": \"VERTEX_LABEL\",\n" + + "\"base_value\": \"person\",\n" + + "\"index_type\": \"SECONDARY\",\n" + + "\"fields\": [\n" + + "\"city\"\n" + + "]\n" + + "}"); + } + protected static void initVertex() { String path = URL_PREFIX + GRAPH_VERTEX; @@ -422,15 +436,32 @@ protected static String assertResponseStatus(int status, return content; } - public static Object assertJsonContains(String response, String key) { + public static T assertJsonContains(String response, String key) { Map json = JsonUtil.fromJson(response, Map.class); return assertMapContains(json, key); } - public static Object assertMapContains(Map map, String key) { + @SuppressWarnings("unchecked") + public static T assertMapContains(Map map, String key) { String message = String.format("Expect contains key '%s' in %s", key, map); Assert.assertTrue(message, map.containsKey(key)); - return map.get(key); + return (T) map.get(key); + } + + @SuppressWarnings("unchecked") + public static Map assertArrayContains(List> list, + String key, Object value) { + String message = String.format("Expect contains {'%s':'%s'} in list %s", + key, value, list); + Map found = null; + for (Map map : list) { + if (map.get(key).equals(value)) { + found = map; + break; + } + } + Assert.assertTrue(message, found != null); + return found; } } diff --git a/hugegraph-test/src/main/java/com/baidu/hugegraph/api/TaskApiTest.java b/hugegraph-test/src/main/java/com/baidu/hugegraph/api/TaskApiTest.java new file mode 100644 index 0000000000..040c22c0de --- /dev/null +++ b/hugegraph-test/src/main/java/com/baidu/hugegraph/api/TaskApiTest.java @@ -0,0 +1,103 @@ +/* + * 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; + +import java.util.List; +import java.util.Map; + +import javax.ws.rs.core.Response; + +import org.junit.Before; +import org.junit.Test; + +import com.baidu.hugegraph.testutil.Assert; + +import jersey.repackaged.com.google.common.collect.ImmutableList; +import jersey.repackaged.com.google.common.collect.ImmutableMap; + +public class TaskApiTest extends BaseApiTest { + + private static String path = "/graphs/hugegraph/tasks/"; + private static String rebuildPath = + "/graphs/hugegraph/jobs/rebuild/indexlabels/personByCity"; + private static String personByCity = "personByCity"; + private static Map personByCityIL = ImmutableMap.of( + "name", "personByCity", + "base_type", "VERTEX_LABEL", + "base_value", "person", + "index_type", "SECONDARY", + "fields", ImmutableList.of("city")); + + @Before + public void prepareSchema() { + BaseApiTest.initPropertyKey(); + BaseApiTest.initVertexLabel(); + BaseApiTest.initIndexLabel(); + } + + @Test + public void testList() { + int taskId = this.rebuild(); + + Response r = client().get(path); + String content = assertResponseStatus(200, r); + List> tasks = assertJsonContains(content, "tasks"); + assertArrayContains(tasks, "id", taskId); + + this.waitTaskSuccess(taskId); + r = client().get(path, ImmutableMap.of("status", "RUNNING")); + content = assertResponseStatus(200, r); + tasks = assertJsonContains(content, "tasks"); + Assert.assertTrue(tasks.isEmpty()); + } + + @Test + public void testGet() { + int taskId = this.rebuild(); + + Response r = client().get(path, String.valueOf(taskId)); + String content = assertResponseStatus(200, r); + assertJsonContains(content, "id"); + } + + @Test + public void testDelete() { + int taskId = this.rebuild(); + + this.waitTaskSuccess(taskId); + Response r = client().delete(path, String.valueOf(taskId)); + assertResponseStatus(204, r); + } + + private int rebuild() { + Response r = client().put(rebuildPath, personByCity, personByCityIL); + String content = assertResponseStatus(202, r); + return assertJsonContains(content, "task_id"); + } + + private void waitTaskSuccess(int task) { + String status; + do { + Response r = client().get(path, String.valueOf(task)); + String content = assertResponseStatus(200, r); + status = assertJsonContains(content, "task_status"); + } while (!status.equals("success")); + } +}