From 9e484eb78ae9a92e4ffc33ccb5574206ccd1e67d Mon Sep 17 00:00:00 2001 From: Anqi Date: Fri, 31 Mar 2023 00:33:39 +0800 Subject: [PATCH] cherrypick to 3.4 (#517) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * check connection by default #401 (#456) * enhancement:support more type value as parameter in session.value2Nvalue (#511) * enhancement:support more type value as parameter in session.value2Nvalue * code style for #511 * code style for #511 * Add maven wrapper (#513) Co-authored-by: Will Droste * recreate session for both session error and connection exception * fix style check * sleep for docker restart --------- Co-authored-by: vchangpengfei <37330503+vchangpengfei@users.noreply.github.com> Co-authored-by: 大叶 Co-authored-by: Will Droste --- .mvn/wrapper/maven-wrapper.properties | 18 ++ .../nebula/client/graph/NebulaSession.java | 4 +- .../nebula/client/graph/SessionPool.java | 34 ++- .../nebula/client/graph/net/NebulaPool.java | 2 + .../nebula/client/graph/net/Session.java | 170 +++++++---- .../com/vesoft/nebula/util/ReflectUtil.java | 85 ++++++ .../client/graph/data/TestDataFromServer.java | 19 +- .../client/graph/net/TestSessionPool.java | 47 +++ mvnw | 287 ++++++++++++++++++ mvnw.cmd | 187 ++++++++++++ 10 files changed, 777 insertions(+), 76 deletions(-) create mode 100644 .mvn/wrapper/maven-wrapper.properties create mode 100644 client/src/main/java/com/vesoft/nebula/util/ReflectUtil.java create mode 100755 mvnw create mode 100644 mvnw.cmd diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 000000000..dc3affce3 --- /dev/null +++ b/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,18 @@ +# 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 +# +# https://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. +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.6/apache-maven-3.8.6-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar diff --git a/client/src/main/java/com/vesoft/nebula/client/graph/NebulaSession.java b/client/src/main/java/com/vesoft/nebula/client/graph/NebulaSession.java index 0d2e0ef9f..ceed867d1 100644 --- a/client/src/main/java/com/vesoft/nebula/client/graph/NebulaSession.java +++ b/client/src/main/java/com/vesoft/nebula/client/graph/NebulaSession.java @@ -73,7 +73,9 @@ public void release() { connection.signout(sessionID); connection.close(); } catch (Exception e) { - log.warn("release session failed, " + e.getMessage()); + // not print the warn to avoid confuse for session and connect, + // when connection is broken, release will failed, just make connection as null. + // log.warn("release session failed, " + e.getMessage()); } connection = null; } diff --git a/client/src/main/java/com/vesoft/nebula/client/graph/SessionPool.java b/client/src/main/java/com/vesoft/nebula/client/graph/SessionPool.java index 2efb63cb5..b0c19eeae 100644 --- a/client/src/main/java/com/vesoft/nebula/client/graph/SessionPool.java +++ b/client/src/main/java/com/vesoft/nebula/client/graph/SessionPool.java @@ -5,6 +5,8 @@ package com.vesoft.nebula.client.graph; +import static com.vesoft.nebula.client.graph.exception.IOErrorException.E_CONNECT_BROKEN; + import com.alibaba.fastjson.JSON; import com.vesoft.nebula.ErrorCode; import com.vesoft.nebula.client.graph.data.HostAddress; @@ -138,22 +140,27 @@ public ResultSet execute(String stmt) throws IOErrorException, stmtCheck(stmt); checkSessionPool(); NebulaSession nebulaSession = getSession(); - ResultSet resultSet; - try { - resultSet = nebulaSession.execute(stmt); - - // re-execute for session error - if (isSessionError(resultSet)) { + ResultSet resultSet = null; + int tryTimes = 3; + while (tryTimes-- > 0) { + try { + resultSet = nebulaSession.execute(stmt); + if (!isSessionError(resultSet)) { + useSpace(nebulaSession, resultSet); + return resultSet; + } else { + throw new IOErrorException(E_CONNECT_BROKEN, resultSet.getErrorMessage()); + } + } catch (IOErrorException e) { nebulaSession.release(); sessionList.remove(nebulaSession); - nebulaSession = getSession(); - resultSet = nebulaSession.execute(stmt); + if (tryTimes > 0) { + nebulaSession = createSessionObject(SessionState.USED); + } else { + throw e; + } } - } catch (IOErrorException e) { - useSpace(nebulaSession, null); - throw e; } - useSpace(nebulaSession, resultSet); return resultSet; } @@ -339,7 +346,8 @@ public HostAddress getAddress() { private void useSpace(NebulaSession nebulaSession, ResultSet resultSet) throws IOErrorException { if (resultSet == null) { - releaseSession(nebulaSession); + nebulaSession.release(); + sessionList.remove(nebulaSession); return; } // space has been drop, close the SessionPool diff --git a/client/src/main/java/com/vesoft/nebula/client/graph/net/NebulaPool.java b/client/src/main/java/com/vesoft/nebula/client/graph/net/NebulaPool.java index 0ffc6a523..262458622 100644 --- a/client/src/main/java/com/vesoft/nebula/client/graph/net/NebulaPool.java +++ b/client/src/main/java/com/vesoft/nebula/client/graph/net/NebulaPool.java @@ -112,6 +112,8 @@ public boolean init(List addresses, NebulaPoolConfig config) objConfig.setMaxTotal(config.getMaxConnSize()); objConfig.setTestOnBorrow(true); objConfig.setTestOnReturn(true); + objConfig.setTestOnCreate(true); + objConfig.setTestWhileIdle(true); objConfig.setTimeBetweenEvictionRunsMillis(config.getIntervalIdle() <= 0 ? BaseObjectPoolConfig.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS : config.getIntervalIdle()); diff --git a/client/src/main/java/com/vesoft/nebula/client/graph/net/Session.java b/client/src/main/java/com/vesoft/nebula/client/graph/net/Session.java index f7fc2af03..aef1e53cf 100644 --- a/client/src/main/java/com/vesoft/nebula/client/graph/net/Session.java +++ b/client/src/main/java/com/vesoft/nebula/client/graph/net/Session.java @@ -5,23 +5,34 @@ package com.vesoft.nebula.client.graph.net; -import com.vesoft.nebula.Date; +import static com.vesoft.nebula.util.ReflectUtil.isCurrentTypeOrParentType; + +import com.vesoft.nebula.DataSet; import com.vesoft.nebula.DateTime; import com.vesoft.nebula.Duration; +import com.vesoft.nebula.Edge; import com.vesoft.nebula.Geography; import com.vesoft.nebula.NList; import com.vesoft.nebula.NMap; +import com.vesoft.nebula.NSet; import com.vesoft.nebula.NullType; +import com.vesoft.nebula.Path; import com.vesoft.nebula.Time; import com.vesoft.nebula.Value; +import com.vesoft.nebula.Vertex; import com.vesoft.nebula.client.graph.data.HostAddress; import com.vesoft.nebula.client.graph.data.ResultSet; import com.vesoft.nebula.client.graph.exception.IOErrorException; import com.vesoft.nebula.graph.ExecutionResponse; +import com.vesoft.nebula.util.ReflectUtil; import java.io.Serializable; +import java.lang.reflect.Field; import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; @@ -414,7 +425,6 @@ private static NMap map2Nmap(Map map) throws UnsupportedOperatio return nmap; } - /** * convert java value type to nebula thrift value type * @@ -422,60 +432,118 @@ private static NMap map2Nmap(Map map) throws UnsupportedOperatio * @return nebula value */ public static Value value2Nvalue(Object value) throws UnsupportedOperationException { - Value nvalue = new Value(); - if (value == null) { - nvalue.setNVal(NullType.__NULL__); - } else if (value instanceof Boolean) { - boolean bval = (Boolean) value; - nvalue.setBVal(bval); - } else if (value instanceof Integer) { - int ival = (Integer) value; - nvalue.setIVal(ival); - } else if (value instanceof Short) { - int ival = (Short) value; - nvalue.setIVal(ival); - } else if (value instanceof Byte) { - int ival = (Byte) value; - nvalue.setIVal(ival); - } else if (value instanceof Long) { - long ival = (Long) value; - nvalue.setIVal(ival); - } else if (value instanceof Float) { - float fval = (Float) value; - nvalue.setFVal(fval); - } else if (value instanceof Double) { - double dval = (Double) value; - nvalue.setFVal(dval); - } else if (value instanceof String) { - byte[] sval = ((String) value).getBytes(); - nvalue.setSVal(sval); - } else if (value instanceof List) { - nvalue.setLVal(list2Nlist((List) value)); - } else if (value instanceof Map) { - nvalue.setMVal(map2Nmap((Map) value)); - } else if (value instanceof Value) { - return (Value) value; - } else if (value instanceof Date) { - nvalue.setDVal((Date) value); - } else if (value instanceof Time) { - nvalue.setTVal((Time) value); - } else if (value instanceof Duration) { - nvalue.setDuVal((Duration) value); - } else if (value instanceof DateTime) { - nvalue.setDtVal((DateTime) value); - } else if (value instanceof Geography) { - nvalue.setGgVal((Geography) value); - } else { - // unsupport other Value type, use this function carefully - throw new UnsupportedOperationException( - "Only support convert boolean/float/int/string/map/list to nebula.Value but was" - + value.getClass().getTypeName()); + try { + if (value == null) { + Value nullValue = new Value(); + nullValue.setNVal(NullType.__NULL__); + return nullValue; + } + Class type = value.getClass(); + Setter setter = LEAF_TYPE_AND_SETTER.get(type); + if (setter != null) { + return setter.set(value); + } + for (Class parentType : COMPLEX_TYPE_AND_SETTER.keySet()) { + if (isCurrentTypeOrParentType(type, parentType)) { + return COMPLEX_TYPE_AND_SETTER.get(parentType).set(value); + } + } + } catch (Exception e) { + throw new UnsupportedOperationException(e); } - return nvalue; + throw new UnsupportedOperationException( + "Only support convert boolean/float/int/string/map/list/date/pojo to nebula.Value but was" + + value.getClass().getTypeName()); } @Override public synchronized void close() { release(); } + + /** + * some value setter for java type (basic or nebula special type) that need convert to NValue + */ + public static Map, Setter> LEAF_TYPE_AND_SETTER = + new HashMap, Setter>() {{ + put(Value.class, (Setter) (param) -> param); + put(Boolean.class, (Setter) Value::bVal); + put(Integer.class, (Setter) Value::iVal); + put(Short.class, (Setter) Value::iVal); + put(Byte.class, (Setter) Value::iVal); + put(Long.class, (Setter) Value::iVal); + put(Float.class, (Setter) Value::fVal); + put(Double.class, (Setter) Value::fVal); + put(byte[].class, (Setter) Value::sVal); + put(Byte[].class, (Setter) Value::sVal); + put(String.class, (Setter) (param) -> Value.sVal(param.getBytes())); + put(com.vesoft.nebula.Date.class, (Setter) Value::dVal); + put(Time.class, (Setter