From 8ff1ef688dcce7b26031c110f570ad3db8baa174 Mon Sep 17 00:00:00 2001 From: Anqi Date: Mon, 25 Dec 2023 15:20:35 +0800 Subject: [PATCH 01/14] add auth for StorageClient scan (#566) * add auth for scan * add test * update the graph address config --- .../nebula/client/storage/StorageClient.java | 137 ++++++++++++++++++ .../client/storage/StorageClientTest.java | 3 + 2 files changed, 140 insertions(+) diff --git a/client/src/main/java/com/vesoft/nebula/client/storage/StorageClient.java b/client/src/main/java/com/vesoft/nebula/client/storage/StorageClient.java index 42fe38c56..ebbf341bd 100644 --- a/client/src/main/java/com/vesoft/nebula/client/storage/StorageClient.java +++ b/client/src/main/java/com/vesoft/nebula/client/storage/StorageClient.java @@ -7,7 +7,14 @@ import com.vesoft.nebula.HostAddr; import com.vesoft.nebula.client.graph.data.HostAddress; +import com.vesoft.nebula.client.graph.data.ResultSet; import com.vesoft.nebula.client.graph.data.SSLParam; +import com.vesoft.nebula.client.graph.data.ValueWrapper; +import com.vesoft.nebula.client.graph.exception.AuthFailedException; +import com.vesoft.nebula.client.graph.exception.ClientServerIncompatibleException; +import com.vesoft.nebula.client.graph.exception.IOErrorException; +import com.vesoft.nebula.client.graph.net.AuthResult; +import com.vesoft.nebula.client.graph.net.SyncConnection; import com.vesoft.nebula.client.meta.MetaManager; import com.vesoft.nebula.client.storage.scan.PartScanInfo; import com.vesoft.nebula.client.storage.scan.ScanEdgeResultIterator; @@ -19,10 +26,13 @@ import com.vesoft.nebula.storage.ScanVertexRequest; import com.vesoft.nebula.storage.VertexProp; import java.io.Serializable; +import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -41,6 +51,15 @@ public class StorageClient implements Serializable { private boolean enableSSL = false; private SSLParam sslParam = null; + private String user = null; + private String password = null; + + private String graphAddresss = null; + + + // the write list for users with read permission + private Map> spaceLabelWriteList = new HashMap<>(); + /** * Get a Nebula Storage client that executes the scan query to get NebulaGraph's data with * one server host. @@ -92,12 +111,31 @@ public StorageClient(List addresses, int timeout, int connectionRet } } + public StorageClient setUser(String user) { + this.user = user; + return this; + } + + public StorageClient setPassword(String password) { + this.password = password; + return this; + } + + public String getGraphAddresss() { + return graphAddresss; + } + + public void setGraphAddresss(String graphAddresss) { + this.graphAddresss = graphAddresss; + } + /** * Connect to Nebula Storage server. * * @return true if connect successfully. */ public boolean connect() throws Exception { + authUser(); connection.open(addresses.get(0), timeout, enableSSL, sslParam); StoragePoolConfig config = new StoragePoolConfig(); config.setEnableSSL(enableSSL); @@ -554,6 +592,15 @@ private ScanVertexResultIterator scanVertex(String spaceName, partScanInfoSet.add(new PartScanInfo(part, new HostAddress(leader.getHost(), leader.getPort()))); } + + // check the user permission after the 'getLeader', + // if the space is not exist, 'getLeader' can throw it first. + if (!checkWriteList(spaceName, tagName)) { + throw new IllegalArgumentException( + String.format("user %s has no read permission for %s.%s", user, spaceName, + tagName)); + } + List addrs = new ArrayList<>(); for (HostAddr addr : metaManager.listHosts()) { addrs.add(new HostAddress(addr.getHost(), addr.getPort())); @@ -997,6 +1044,10 @@ private ScanEdgeResultIterator scanEdge(String spaceName, long endTime, boolean allowPartSuccess, boolean allowReadFromFollower) { + if (!checkWriteList(spaceName, edgeName)) { + throw new IllegalArgumentException( + String.format("user has no read permission for %s.%s", spaceName, edgeName)); + } if (spaceName == null || spaceName.trim().isEmpty()) { throw new IllegalArgumentException("space name is empty."); } @@ -1132,6 +1183,92 @@ private long getEdgeId(String spaceName, String edgeName) { return metaManager.getEdge(spaceName, edgeName).getEdge_type(); } + + /** + * auth user with graphd server, and get the space and labels WriteList with read permission + * for user + */ + private void authUser() throws AuthFailedException, IOErrorException, + ClientServerIncompatibleException, UnsupportedEncodingException { + if (user == null || password == null || graphAddresss == null) { + throw new IllegalArgumentException( + "the user,password,graphAddress can not be null," + + " please config them first by setXXX()"); + } + SyncConnection graphConnection = new SyncConnection(); + String[] graphAddrAndPort = graphAddresss.split(":"); + if (graphAddrAndPort.length != 2) { + throw new IllegalArgumentException("the graph address is invalid."); + } + graphConnection.open(new HostAddress(graphAddrAndPort[0].trim(), + Integer.valueOf(graphAddrAndPort[1].trim())), timeout); + AuthResult authResult = graphConnection.authenticate(user, password); + long sessionId = authResult.getSessionId(); + ResultSet resultSet = new ResultSet( + graphConnection.execute(sessionId, "DESC USER " + user), + authResult.getTimezoneOffset()); + if (!resultSet.isSucceeded()) { + throw new RuntimeException("get spaces for user " + user + " failed, " + + resultSet.getErrorMessage()); + } + if (resultSet.isEmpty()) { + throw new RuntimeException("there's no space for user " + user + " to have permission" + + " to access."); + } + + for (int i = 0; i < resultSet.getRows().size(); i++) { + List values = resultSet.rowValues(i).values(); + String role = values.get(0).asString(); + String space = values.get(1).asString(); + if (!role.equalsIgnoreCase("BASIC")) { + spaceLabelWriteList.put(space, null); + } else { + List labels = new ArrayList<>(); + // get the tags and edges that the user has read permission for + String showGrants = String.format("USE %s; show grants %s", space, user); + ResultSet userGrantResult = new ResultSet(graphConnection.execute(sessionId, + showGrants), + authResult.getTimezoneOffset()); + if (!userGrantResult.isSucceeded()) { + throw new RuntimeException("get tags for user " + user + + " failed, " + userGrantResult.getErrorMessage()); + } + List readTags = userGrantResult.colValues("READ(TAG)"); + if (!readTags.isEmpty()) { + for (ValueWrapper v : readTags.get(0).asList()) { + labels.add(v.asString()); + } + } + List readEdges = userGrantResult.colValues("READ(EDGE)"); + if (!readEdges.isEmpty()) { + for (ValueWrapper v : readEdges.get(0).asList()) { + labels.add(v.asString()); + } + } + spaceLabelWriteList.put(space, labels); + } + } + } + + + /** + * check if the space and the label is in the WriteList + * + * @param spaceName space name + * @param label tag name or edge type name + * @return true if spaceName and label in the WriteList + */ + private boolean checkWriteList(String spaceName, String label) { + if (!spaceLabelWriteList.containsKey(spaceName)) { + return false; + } + if (spaceLabelWriteList.get(spaceName) != null + && !spaceLabelWriteList.get(spaceName).contains(label)) { + return false; + } + return true; + } + private static final int DEFAULT_LIMIT = 1000; private static final long DEFAULT_START_TIME = 0; private static final long DEFAULT_END_TIME = Long.MAX_VALUE; diff --git a/client/src/test/java/com/vesoft/nebula/client/storage/StorageClientTest.java b/client/src/test/java/com/vesoft/nebula/client/storage/StorageClientTest.java index d1f8f36d3..780062b87 100644 --- a/client/src/test/java/com/vesoft/nebula/client/storage/StorageClientTest.java +++ b/client/src/test/java/com/vesoft/nebula/client/storage/StorageClientTest.java @@ -43,6 +43,9 @@ public void before() { assert (false); } client = new StorageClient(address); + client.setGraphAddresss(ip + ":9669"); + client.setUser("root"); + client.setPassword("nebula"); } @After From b4a5ae834099de2e26f1ce1caae9269b0dfa6c40 Mon Sep 17 00:00:00 2001 From: Anqi Date: Mon, 25 Dec 2023 16:02:11 +0800 Subject: [PATCH 02/14] cherry-pick 'support to config the version white list' --- .../nebula/client/graph/NebulaPoolConfig.java | 11 +++ .../nebula/client/graph/SessionPool.java | 6 +- .../client/graph/SessionPoolConfig.java | 10 ++ .../client/graph/net/ConnObjectPool.java | 6 +- .../nebula/client/graph/net/Connection.java | 5 +- .../nebula/client/graph/net/NebulaPool.java | 53 +++++----- .../graph/net/RoundRobinLoadBalancer.java | 21 ++-- .../client/graph/net/SyncConnection.java | 26 +++-- .../vesoft/nebula/client/meta/MetaClient.java | 24 ++++- .../nebula/client/meta/MetaManager.java | 25 +++++ .../nebula/client/storage/StorageClient.java | 23 +++-- .../client/graph/net/TestConnectionPool.java | 96 ++++++++++++++----- .../nebula/client/meta/TestMetaClient.java | 32 +++++++ .../client/storage/StorageClientTest.java | 33 ++++++- client/src/test/resources/docker-compose.yaml | 14 ++- .../nebula/examples/GraphClientExample.java | 5 +- 16 files changed, 303 insertions(+), 87 deletions(-) diff --git a/client/src/main/java/com/vesoft/nebula/client/graph/NebulaPoolConfig.java b/client/src/main/java/com/vesoft/nebula/client/graph/NebulaPoolConfig.java index c76b2edb6..889f81ef8 100644 --- a/client/src/main/java/com/vesoft/nebula/client/graph/NebulaPoolConfig.java +++ b/client/src/main/java/com/vesoft/nebula/client/graph/NebulaPoolConfig.java @@ -50,6 +50,9 @@ public class NebulaPoolConfig implements Serializable { // Set custom headers for http2 private Map customHeaders = new HashMap<>(); + // set version for client + private String version = null; + public boolean isEnableSsl() { return enableSsl; } @@ -146,4 +149,12 @@ public NebulaPoolConfig setCustomHeaders(Map customHeaders) { this.customHeaders = customHeaders; return this; } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } } 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 f9e4abdf0..8a7bb9c5f 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 @@ -351,11 +351,13 @@ private NebulaSession createSessionObject(SessionState state) connection.open(getAddress(), sessionPoolConfig.getTimeout(), sessionPoolConfig.getSslParam(), sessionPoolConfig.isUseHttp2(), - sessionPoolConfig.getCustomHeaders()); + sessionPoolConfig.getCustomHeaders(), + sessionPoolConfig.getVersion()); } else { connection.open(getAddress(), sessionPoolConfig.getTimeout(), sessionPoolConfig.isUseHttp2(), - sessionPoolConfig.getCustomHeaders()); + sessionPoolConfig.getCustomHeaders(), + sessionPoolConfig.getVersion()); } break; } catch (Exception e) { diff --git a/client/src/main/java/com/vesoft/nebula/client/graph/SessionPoolConfig.java b/client/src/main/java/com/vesoft/nebula/client/graph/SessionPoolConfig.java index f5a66875a..0a1e20ebb 100644 --- a/client/src/main/java/com/vesoft/nebula/client/graph/SessionPoolConfig.java +++ b/client/src/main/java/com/vesoft/nebula/client/graph/SessionPoolConfig.java @@ -63,6 +63,8 @@ public class SessionPoolConfig implements Serializable { private Map customHeaders = new HashMap<>(); + private String version = null; + public SessionPoolConfig(List addresses, String spaceName, @@ -256,6 +258,14 @@ public SessionPoolConfig setCustomHeaders(Map customHeaders) { return this; } + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + @Override public String toString() { return "SessionPoolConfig{" diff --git a/client/src/main/java/com/vesoft/nebula/client/graph/net/ConnObjectPool.java b/client/src/main/java/com/vesoft/nebula/client/graph/net/ConnObjectPool.java index d9e215fe5..b8a770091 100644 --- a/client/src/main/java/com/vesoft/nebula/client/graph/net/ConnObjectPool.java +++ b/client/src/main/java/com/vesoft/nebula/client/graph/net/ConnObjectPool.java @@ -39,11 +39,11 @@ public SyncConnection create() throws IOErrorException, ClientServerIncompatible throw new IllegalArgumentException("SSL Param is required when enableSsl " + "is set to true"); } - conn.open(address, config.getTimeout(), - config.getSslParam(), config.isUseHttp2(), config.getCustomHeaders()); + conn.open(address, config.getTimeout(), config.getSslParam(), + config.isUseHttp2(), config.getCustomHeaders(), config.getVersion()); } else { conn.open(address, config.getTimeout(), - config.isUseHttp2(), config.getCustomHeaders()); + config.isUseHttp2(), config.getCustomHeaders(), config.getVersion()); } return conn; } catch (IOErrorException e) { diff --git a/client/src/main/java/com/vesoft/nebula/client/graph/net/Connection.java b/client/src/main/java/com/vesoft/nebula/client/graph/net/Connection.java index bd871f530..c123648ef 100644 --- a/client/src/main/java/com/vesoft/nebula/client/graph/net/Connection.java +++ b/client/src/main/java/com/vesoft/nebula/client/graph/net/Connection.java @@ -21,7 +21,8 @@ public abstract void open(HostAddress address, int timeout, SSLParam sslParam) throws IOErrorException, ClientServerIncompatibleException; public abstract void open(HostAddress address, int timeout, - SSLParam sslParam, boolean isUseHttp2, Map headers) + SSLParam sslParam, boolean isUseHttp2, Map headers, + String version) throws IOErrorException, ClientServerIncompatibleException; @@ -29,7 +30,7 @@ public abstract void open(HostAddress address, int timeout) throws IOErrorExcept ClientServerIncompatibleException; public abstract void open(HostAddress address, int timeout, - boolean isUseHttp2, Map headers) + boolean isUseHttp2, Map headers, String version) throws IOErrorException, ClientServerIncompatibleException; public abstract void reopen() throws IOErrorException, ClientServerIncompatibleException; 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 882023601..de97c1f52 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 @@ -40,27 +40,27 @@ public class NebulaPool implements Serializable { private void checkConfig(NebulaPoolConfig config) { if (config.getIdleTime() < 0) { throw new InvalidConfigException( - "Config idleTime:" + config.getIdleTime() + " is illegal"); + "Config idleTime:" + config.getIdleTime() + " is illegal"); } if (config.getMaxConnSize() <= 0) { throw new InvalidConfigException( - "Config maxConnSize:" + config.getMaxConnSize() + " is illegal"); + "Config maxConnSize:" + config.getMaxConnSize() + " is illegal"); } if (config.getMinConnSize() < 0 || config.getMinConnSize() > config.getMaxConnSize()) { throw new InvalidConfigException( - "Config minConnSize:" + config.getMinConnSize() + " is illegal"); + "Config minConnSize:" + config.getMinConnSize() + " is illegal"); } if (config.getTimeout() < 0) { throw new InvalidConfigException( - "Config timeout:" + config.getTimeout() + " is illegal"); + "Config timeout:" + config.getTimeout() + " is illegal"); } if (config.getWaitTime() < 0) { throw new InvalidConfigException( - "Config waitTime:" + config.getWaitTime() + " is illegal"); + "Config waitTime:" + config.getWaitTime() + " is illegal"); } if (config.getMinClusterHealthRate() < 0) { @@ -72,23 +72,24 @@ private void checkConfig(NebulaPoolConfig config) { /** * @param addresses the graphd services addresses - * @param config the config for the pool - * @return boolean if all graph services are ok, return true, - * if some of them broken return false - * @throws UnknownHostException if host address is illegal + * @param config the config for the pool + * @return boolean if all graph services are ok, return true,if some of them broken return false + * @throws UnknownHostException if host address is illegal * @throws InvalidConfigException if config is illegal */ public boolean init(List addresses, NebulaPoolConfig config) - throws UnknownHostException, InvalidConfigException { + throws UnknownHostException, InvalidConfigException { checkInit(); hasInit.set(true); checkConfig(config); this.waitTime = config.getWaitTime(); this.loadBalancer = config.isEnableSsl() ? new RoundRobinLoadBalancer(addresses, config.getTimeout(), config.getSslParam(), - config.getMinClusterHealthRate(), config.isUseHttp2(), config.getCustomHeaders()) + config.getMinClusterHealthRate(), config.isUseHttp2(), config.getCustomHeaders(), + config.getVersion()) : new RoundRobinLoadBalancer(addresses, config.getTimeout(), - config.getMinClusterHealthRate(),config.isUseHttp2(), config.getCustomHeaders()); + config.getMinClusterHealthRate(), config.isUseHttp2(), config.getCustomHeaders(), + config.getVersion()); ConnObjectPool objectPool = new ConnObjectPool(this.loadBalancer, config); this.objectPool = new GenericObjectPool<>(objectPool); GenericObjectPoolConfig objConfig = new GenericObjectPoolConfig(); @@ -100,11 +101,11 @@ public boolean init(List addresses, NebulaPoolConfig config) objConfig.setTestOnCreate(true); objConfig.setTestWhileIdle(true); objConfig.setTimeBetweenEvictionRunsMillis(config.getIntervalIdle() <= 0 - ? BaseObjectPoolConfig.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS - : config.getIntervalIdle()); + ? BaseObjectPoolConfig.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS + : config.getIntervalIdle()); objConfig.setSoftMinEvictableIdleTimeMillis(config.getIdleTime() <= 0 - ? BaseObjectPoolConfig.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS - : config.getIdleTime()); + ? BaseObjectPoolConfig.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS + : config.getIdleTime()); this.objectPool.setConfig(objConfig); AbandonedConfig abandonedConfig = new AbandonedConfig(); @@ -127,13 +128,14 @@ public void close() { /** * get a session from the NebulaPool - * @param userName the userName to authenticate with nebula-graph - * @param password the password to authenticate with nebula-graph + * + * @param userName the userName to authenticate with nebula-graph + * @param password the password to authenticate with nebula-graph * @param reconnect whether to retry after the connection is disconnected * @return Session * @throws NotValidConnectionException if get connection failed - * @throws IOErrorException if get unexpected exception - * @throws AuthFailedException if authenticate failed + * @throws IOErrorException if get unexpected exception + * @throws AuthFailedException if authenticate failed */ public Session getSession(String userName, String password, boolean reconnect) throws NotValidConnectionException, IOErrorException, AuthFailedException, @@ -156,6 +158,7 @@ public Session getSession(String userName, String password, boolean reconnect) /** * Get the number of connections was used by users + * * @return the active connection number */ public int getActiveConnNum() { @@ -165,6 +168,7 @@ public int getActiveConnNum() { /** * Get the number of free connections in the pool + * * @return the idle connection number */ public int getIdleConnNum() { @@ -174,6 +178,7 @@ public int getIdleConnNum() { /** * Get the number of waits in a waiting get connection + * * @return the waiting connection number */ public int getWaitersNum() { @@ -194,6 +199,7 @@ protected void updateServerStatus() { /** * Set the connection is invalidate, and the object pool will destroy it + * * @param connection the invalidate connection */ protected void setInvalidateConnection(SyncConnection connection) { @@ -207,6 +213,7 @@ protected void setInvalidateConnection(SyncConnection connection) { /** * Return the connection to object pool + * * @param connection the return connection */ protected void returnConnection(SyncConnection connection) { @@ -226,15 +233,15 @@ protected SyncConnection getConnection() throws NotValidConnectionException { private void checkNoInit() throws RuntimeException { if (!hasInit.get()) { throw new RuntimeException( - "The pool has not been initialized, please initialize it first."); + "The pool has not been initialized, please initialize it first."); } } private void checkInit() throws RuntimeException { if (hasInit.get()) { throw new RuntimeException( - "The pool has already been initialized. " - + "Please do not initialize the pool repeatedly."); + "The pool has already been initialized. " + + "Please do not initialize the pool repeatedly."); } } diff --git a/client/src/main/java/com/vesoft/nebula/client/graph/net/RoundRobinLoadBalancer.java b/client/src/main/java/com/vesoft/nebula/client/graph/net/RoundRobinLoadBalancer.java index 04f77a919..97546c568 100644 --- a/client/src/main/java/com/vesoft/nebula/client/graph/net/RoundRobinLoadBalancer.java +++ b/client/src/main/java/com/vesoft/nebula/client/graph/net/RoundRobinLoadBalancer.java @@ -34,14 +34,16 @@ public class RoundRobinLoadBalancer implements LoadBalancer { private Map customHeaders; + private String version = null; + public RoundRobinLoadBalancer(List addresses, int timeout, - double minClusterHealthRate) { - this(addresses, timeout, minClusterHealthRate, false, new HashMap<>()); + double minClusterHealthRate, String version) { + this(addresses, timeout, minClusterHealthRate, false, new HashMap<>(), version); } public RoundRobinLoadBalancer(List addresses, int timeout, double minClusterHealthRate, boolean useHttp2, - Map headers) { + Map headers, String version) { this.timeout = timeout; for (HostAddress addr : addresses) { this.addresses.add(addr); @@ -50,18 +52,19 @@ public RoundRobinLoadBalancer(List addresses, int timeout, this.minClusterHealthRate = minClusterHealthRate; this.useHttp2 = useHttp2; this.customHeaders = headers; + this.version = version; schedule.scheduleAtFixedRate(this::scheduleTask, 0, delayTime, TimeUnit.SECONDS); } public RoundRobinLoadBalancer(List addresses, int timeout, SSLParam sslParam, - double minClusterHealthRate) { - this(addresses, timeout, sslParam, minClusterHealthRate, false, new HashMap<>()); + double minClusterHealthRate, String version) { + this(addresses, timeout, sslParam, minClusterHealthRate, false, new HashMap<>(), version); } public RoundRobinLoadBalancer(List addresses, int timeout, SSLParam sslParam, double minClusterHealthRate, boolean useHttp2, - Map headers) { - this(addresses, timeout, minClusterHealthRate, useHttp2, headers); + Map headers, String version) { + this(addresses, timeout, minClusterHealthRate, useHttp2, headers, version); this.sslParam = sslParam; this.enabledSsl = true; } @@ -101,9 +104,9 @@ public boolean ping(HostAddress addr) { try { Connection connection = new SyncConnection(); if (enabledSsl) { - connection.open(addr, this.timeout, sslParam, useHttp2, customHeaders); + connection.open(addr, this.timeout, sslParam, useHttp2, customHeaders, version); } else { - connection.open(addr, this.timeout, useHttp2, customHeaders); + connection.open(addr, this.timeout, useHttp2, customHeaders, version); } boolean pong = connection.ping(); connection.close(); diff --git a/client/src/main/java/com/vesoft/nebula/client/graph/net/SyncConnection.java b/client/src/main/java/com/vesoft/nebula/client/graph/net/SyncConnection.java index 74ea2ec1f..a310dceb4 100644 --- a/client/src/main/java/com/vesoft/nebula/client/graph/net/SyncConnection.java +++ b/client/src/main/java/com/vesoft/nebula/client/graph/net/SyncConnection.java @@ -56,15 +56,17 @@ public class SyncConnection extends Connection { private Map headers = new HashMap<>(); + private String versionInfo = null; + @Override public void open(HostAddress address, int timeout, SSLParam sslParam) throws IOErrorException, ClientServerIncompatibleException { - this.open(address, timeout, sslParam, false, headers); + this.open(address, timeout, sslParam, false, headers, versionInfo); } @Override public void open(HostAddress address, int timeout, SSLParam sslParam, boolean isUseHttp2, - Map headers) + Map headers, String version) throws IOErrorException, ClientServerIncompatibleException { try { this.serverAddr = address; @@ -73,6 +75,7 @@ public void open(HostAddress address, int timeout, SSLParam sslParam, boolean is this.sslParam = sslParam; this.useHttp2 = isUseHttp2; this.headers = headers; + this.versionInfo = version; if (sslSocketFactory == null) { if (sslParam.getSignMode() == SSLParam.SignMode.CA_SIGNED) { sslSocketFactory = @@ -91,6 +94,10 @@ public void open(HostAddress address, int timeout, SSLParam sslParam, boolean is client = new GraphService.Client(protocol); // check if client version matches server version + VerifyClientVersionReq verifyClientVersionReq = new VerifyClientVersionReq(); + if (versionInfo != null) { + verifyClientVersionReq.setVersion(versionInfo.getBytes(Charsets.UTF_8)); + } VerifyClientVersionResp resp = client.verifyClientVersion(new VerifyClientVersionReq()); if (resp.error_code != ErrorCode.SUCCEEDED) { @@ -107,18 +114,19 @@ public void open(HostAddress address, int timeout, SSLParam sslParam, boolean is @Override public void open(HostAddress address, int timeout) throws IOErrorException, ClientServerIncompatibleException { - this.open(address, timeout, false, headers); + this.open(address, timeout, false, headers, versionInfo); } @Override public void open(HostAddress address, int timeout, - boolean isUseHttp2, Map headers) + boolean isUseHttp2, Map headers, String version) throws IOErrorException, ClientServerIncompatibleException { try { this.serverAddr = address; this.timeout = timeout <= 0 ? Integer.MAX_VALUE : timeout; this.useHttp2 = isUseHttp2; this.headers = headers; + this.versionInfo = version; if (useHttp2) { getProtocolForHttp2(); } else { @@ -127,8 +135,12 @@ public void open(HostAddress address, int timeout, client = new GraphService.Client(protocol); // check if client version matches server version + VerifyClientVersionReq verifyClientVersionReq = new VerifyClientVersionReq(); + if (versionInfo != null) { + verifyClientVersionReq.setVersion(versionInfo.getBytes(Charsets.UTF_8)); + } VerifyClientVersionResp resp = - client.verifyClientVersion(new VerifyClientVersionReq()); + client.verifyClientVersion(verifyClientVersionReq); if (resp.error_code != ErrorCode.SUCCEEDED) { client.getInputProtocol().getTransport().close(); throw new ClientServerIncompatibleException(new String(resp.getError_msg(), @@ -207,9 +219,9 @@ private void getProtocol() { public void reopen() throws IOErrorException, ClientServerIncompatibleException { close(); if (enabledSsl) { - open(serverAddr, timeout, sslParam, useHttp2, headers); + open(serverAddr, timeout, sslParam, useHttp2, headers, versionInfo); } else { - open(serverAddr, timeout, useHttp2, headers); + open(serverAddr, timeout, useHttp2, headers, versionInfo); } } diff --git a/client/src/main/java/com/vesoft/nebula/client/meta/MetaClient.java b/client/src/main/java/com/vesoft/nebula/client/meta/MetaClient.java index 0681ec79a..c534999d5 100644 --- a/client/src/main/java/com/vesoft/nebula/client/meta/MetaClient.java +++ b/client/src/main/java/com/vesoft/nebula/client/meta/MetaClient.java @@ -79,6 +79,8 @@ public class MetaClient extends AbstractMetaClient { private MetaService.Client client; private final List addresses; + private String version = null; + public MetaClient(String host, int port) throws UnknownHostException { this(new HostAddress(host, port)); } @@ -114,6 +116,17 @@ public MetaClient(List addresses, int timeout, int connectionRetry, } } + /** + * set the version info for MetaClient + * + * @param version version info + * @return MetaClient + */ + public MetaClient setVersion(String version) { + this.version = version; + return this; + } + public void connect() throws TException, ClientServerIncompatibleException { doConnect(); @@ -155,8 +168,11 @@ private void getClient(String host, int port) client = new MetaService.Client(protocol); // check if client version matches server version - VerifyClientVersionResp resp = client - .verifyClientVersion(new VerifyClientVersionReq()); + VerifyClientVersionReq verifyClientVersionReq = new VerifyClientVersionReq(); + if (version != null) { + verifyClientVersionReq.setClient_version(version.getBytes(Charsets.UTF_8)); + } + VerifyClientVersionResp resp = client.verifyClientVersion(verifyClientVersionReq); if (resp.getCode() != ErrorCode.SUCCEEDED) { client.getInputProtocol().getTransport().close(); if (resp.getError_msg() == null) { @@ -164,9 +180,7 @@ private void getClient(String host, int port) new String("Error code: ") + String.valueOf(resp.getCode().getValue())); } - throw new ClientServerIncompatibleException( - new String(resp.getError_msg()) - + String.valueOf(resp.getCode().getValue())); + throw new ClientServerIncompatibleException(new String(resp.getError_msg())); } } diff --git a/client/src/main/java/com/vesoft/nebula/client/meta/MetaManager.java b/client/src/main/java/com/vesoft/nebula/client/meta/MetaManager.java index 4b3294a25..8e34c46b2 100644 --- a/client/src/main/java/com/vesoft/nebula/client/meta/MetaManager.java +++ b/client/src/main/java/com/vesoft/nebula/client/meta/MetaManager.java @@ -63,6 +63,18 @@ public MetaManager(List address) fillMetaInfo(); } + /** + * init the meta info cache with client version + */ + public MetaManager(List address, String version) + throws TException, ClientServerIncompatibleException, UnknownHostException { + metaClient = new MetaClient(address); + metaClient.setVersion(version); + metaClient.connect(); + fillMetaInfo(); + } + + /** * init the meta info cache with more config */ @@ -75,6 +87,19 @@ public MetaManager(List address, int timeout, int connectionRetry, fillMetaInfo(); } + /** + * init the meta info cache with more config + */ + public MetaManager(List address, int timeout, int connectionRetry, + int executionRetry, boolean enableSSL, SSLParam sslParam, String version) + throws TException, ClientServerIncompatibleException, UnknownHostException { + metaClient = new MetaClient(address, timeout, connectionRetry, executionRetry, enableSSL, + sslParam); + metaClient.setVersion(version); + metaClient.connect(); + fillMetaInfo(); + } + /** * close meta client */ diff --git a/client/src/main/java/com/vesoft/nebula/client/storage/StorageClient.java b/client/src/main/java/com/vesoft/nebula/client/storage/StorageClient.java index ebbf341bd..0ba9db9c3 100644 --- a/client/src/main/java/com/vesoft/nebula/client/storage/StorageClient.java +++ b/client/src/main/java/com/vesoft/nebula/client/storage/StorageClient.java @@ -54,11 +54,11 @@ public class StorageClient implements Serializable { private String user = null; private String password = null; - private String graphAddresss = null; - + private String graphAddress = null; // the write list for users with read permission private Map> spaceLabelWriteList = new HashMap<>(); + private String version = null; /** * Get a Nebula Storage client that executes the scan query to get NebulaGraph's data with @@ -121,12 +121,17 @@ public StorageClient setPassword(String password) { return this; } - public String getGraphAddresss() { - return graphAddresss; + public String getGraphAddress() { + return graphAddress; + } + + public void setGraphAddress(String graphAddress) { + this.graphAddress = graphAddress; } - public void setGraphAddresss(String graphAddresss) { - this.graphAddresss = graphAddresss; + public StorageClient setVersion(String version) { + this.version = version; + return this; } /** @@ -142,7 +147,7 @@ public boolean connect() throws Exception { config.setSslParam(sslParam); pool = new StorageConnPool(config); metaManager = new MetaManager(addresses, timeout, connectionRetry, executionRetry, - enableSSL, sslParam); + enableSSL, sslParam, version); return true; } @@ -1190,13 +1195,13 @@ private long getEdgeId(String spaceName, String edgeName) { */ private void authUser() throws AuthFailedException, IOErrorException, ClientServerIncompatibleException, UnsupportedEncodingException { - if (user == null || password == null || graphAddresss == null) { + if (user == null || password == null || graphAddress == null) { throw new IllegalArgumentException( "the user,password,graphAddress can not be null," + " please config them first by setXXX()"); } SyncConnection graphConnection = new SyncConnection(); - String[] graphAddrAndPort = graphAddresss.split(":"); + String[] graphAddrAndPort = graphAddress.split(":"); if (graphAddrAndPort.length != 2) { throw new IllegalArgumentException("the graph address is invalid."); } diff --git a/client/src/test/java/com/vesoft/nebula/client/graph/net/TestConnectionPool.java b/client/src/test/java/com/vesoft/nebula/client/graph/net/TestConnectionPool.java index a7a88d991..9eb47d4da 100644 --- a/client/src/test/java/com/vesoft/nebula/client/graph/net/TestConnectionPool.java +++ b/client/src/test/java/com/vesoft/nebula/client/graph/net/TestConnectionPool.java @@ -9,6 +9,7 @@ import com.vesoft.nebula.client.graph.NebulaPoolConfig; import com.vesoft.nebula.client.graph.data.HostAddress; import com.vesoft.nebula.client.graph.data.ResultSet; +import com.vesoft.nebula.client.graph.exception.ClientServerIncompatibleException; import com.vesoft.nebula.client.graph.exception.IOErrorException; import com.vesoft.nebula.client.graph.exception.InvalidConfigException; import java.net.UnknownHostException; @@ -29,8 +30,8 @@ public void testInitFailed() { NebulaPoolConfig config = new NebulaPoolConfig(); config.setIdleTime(-10); pool.init( - Collections.singletonList(new HostAddress("127.0.0.1", 3777)), - config); + Collections.singletonList(new HostAddress("127.0.0.1", 3777)), + config); assert false; } catch (UnknownHostException e) { System.out.println("We expect must reach here: init pool failed."); @@ -46,8 +47,8 @@ public void testInitFailed() { NebulaPoolConfig config = new NebulaPoolConfig(); config.setMaxConnSize(-10); pool.init( - Collections.singletonList(new HostAddress("127.0.0.1", 3777)), - config); + Collections.singletonList(new HostAddress("127.0.0.1", 3777)), + config); assert false; } catch (UnknownHostException e) { System.out.println("We expect must reach here: init pool failed."); @@ -64,10 +65,10 @@ public void testInitFailed() { config.setMaxConnSize(10); config.setMinConnSize(20); pool.init( - Collections.singletonList(new HostAddress("127.0.0.1", 3777)), - config); + Collections.singletonList(new HostAddress("127.0.0.1", 3777)), + config); assert false; - } catch (UnknownHostException e) { + } catch (UnknownHostException e) { System.out.println("We expect must reach here: init pool failed."); assert false; } catch (InvalidConfigException e) { @@ -81,8 +82,8 @@ public void testInitFailed() { NebulaPoolConfig config = new NebulaPoolConfig(); config.setTimeout(-10); pool.init( - Collections.singletonList(new HostAddress("127.0.0.1", 3777)), - config); + Collections.singletonList(new HostAddress("127.0.0.1", 3777)), + config); assert false; } catch (UnknownHostException e) { System.out.println("We expect must reach here: init pool failed."); @@ -95,7 +96,7 @@ public void testInitFailed() { // hostname is not existed try { List addresses = Collections.singletonList( - new HostAddress("hostname", 3888)); + new HostAddress("hostname", 3888)); NebulaPool pool = new NebulaPool(); Assert.assertFalse(pool.init(addresses, new NebulaPoolConfig())); } catch (UnknownHostException e) { @@ -109,7 +110,7 @@ public void testInitFailed() { nebulaPoolConfig.setMinConnSize(0); nebulaPoolConfig.setMaxConnSize(1); List addresses = Collections.singletonList( - new HostAddress("127.0.0.1", 3888)); + new HostAddress("127.0.0.1", 3888)); NebulaPool pool = new NebulaPool(); Assert.assertFalse(pool.init(addresses, nebulaPoolConfig)); } catch (Exception e) { @@ -118,6 +119,53 @@ public void testInitFailed() { } } + @Test + public void testDefaultVersion() { + try { + NebulaPool pool = new NebulaPool(); + NebulaPoolConfig config = new NebulaPoolConfig(); + pool.init( + Collections.singletonList(new HostAddress("127.0.0.1", 9669)), + config); + assert true; + } catch (Exception e) { + e.printStackTrace(); + assert false; + } + } + + @Test + public void testVersionInWhiteList() { + try { + NebulaPool pool = new NebulaPool(); + NebulaPoolConfig config = new NebulaPoolConfig(); + config.setVersion("test"); + pool.init( + Collections.singletonList(new HostAddress("127.0.0.1", 9669)), + config); + assert true; + } catch (Exception e) { + e.printStackTrace(); + assert false; + } + } + + @Test + public void testVersionNotInWhiteList() { + try { + NebulaPool pool = new NebulaPool(); + NebulaPoolConfig config = new NebulaPoolConfig(); + config.setVersion("INVALID_VERSION"); + boolean initResult = pool.init( + Collections.singletonList(new HostAddress("127.0.0.1", 9669)), + config); + assert !initResult; + } catch (Exception e) { + e.printStackTrace(); + assert false; + } + } + @Test() public void testGetSession() { NebulaPool pool = null; @@ -132,7 +180,7 @@ public void testGetSession() { // set wait time nebulaPoolConfig.setWaitTime(1000); List addresses = Collections.singletonList( - new HostAddress("127.0.0.1", 9671)); + new HostAddress("127.0.0.1", 9671)); pool = new NebulaPool(); assert pool.init(addresses, nebulaPoolConfig); int i = 0; @@ -157,7 +205,7 @@ public void testGetSession() { } catch (Exception e) { System.out.println(e.getMessage()); System.out.println("We expect must reach here: get session failed."); - long timeInterval = System.currentTimeMillis() - beginTime; + long timeInterval = System.currentTimeMillis() - beginTime; System.out.println("timeInterval is " + timeInterval); Assert.assertTrue(System.currentTimeMillis() - beginTime >= 1000); assert (true); @@ -202,8 +250,8 @@ public void testInitAndClose() { assert false; } catch (Exception e) { Assert.assertTrue( - e.getMessage().contains( - "The pool has not been initialized, please initialize it first.")); + e.getMessage().contains( + "The pool has not been initialized, please initialize it first.")); System.out.println("We expect must reach here: init pool failed."); assert true; } @@ -211,18 +259,18 @@ public void testInitAndClose() { // init twice try { pool.init( - Collections.singletonList(new HostAddress("127.0.0.1", 9669)), - new NebulaPoolConfig()); + Collections.singletonList(new HostAddress("127.0.0.1", 9669)), + new NebulaPoolConfig()); assert true; pool.init( - Collections.singletonList(new HostAddress("127.0.0.1", 9669)), - new NebulaPoolConfig()); + Collections.singletonList(new HostAddress("127.0.0.1", 9669)), + new NebulaPoolConfig()); assert false; } catch (Exception e) { Assert.assertTrue( - e.getMessage().contains( - "The pool has already been initialized. " - + "Please do not initialize the pool repeatedly")); + e.getMessage().contains( + "The pool has already been initialized. " + + "Please do not initialize the pool repeatedly")); System.out.println("We expect must reach here: init pool failed."); assert true; } @@ -248,14 +296,14 @@ public void testExecuteTimeout() { nebulaPoolConfig.setMaxConnSize(1); nebulaPoolConfig.setTimeout(1000); List addresses = Collections.singletonList( - new HostAddress("127.0.0.1", 9669)); + new HostAddress("127.0.0.1", 9669)); pool = new NebulaPool(); assert pool.init(addresses, nebulaPoolConfig); session = pool.getSession("root", "nebula", false); assert (session != null); try { session.execute( - "USE nba;GO 600 STEPS FROM \"Tim Duncan\" OVER like"); + "USE nba;GO 600 STEPS FROM \"Tim Duncan\" OVER like"); assert false; } catch (IOErrorException e) { Assert.assertTrue(e.getMessage().contains("Read timed out")); diff --git a/client/src/test/java/com/vesoft/nebula/client/meta/TestMetaClient.java b/client/src/test/java/com/vesoft/nebula/client/meta/TestMetaClient.java index 2e15675f2..7871bbcf3 100644 --- a/client/src/test/java/com/vesoft/nebula/client/meta/TestMetaClient.java +++ b/client/src/test/java/com/vesoft/nebula/client/meta/TestMetaClient.java @@ -64,6 +64,38 @@ public void testFailConnect() { } } + + public void testConnectWithVersionInWhiteList() { + int port = 9559; + try { + MetaClient client = new MetaClient(address, port); + client.setVersion("3.0.0"); + client.connect(); + + client.setVersion("test"); + client.connect(); + } catch (TException | UnknownHostException | ClientServerIncompatibleException e) { + e.printStackTrace(); + assert (false); + } + } + + + public void testConnectWithVersionNotInWhiteList() { + int port = 9559; + try { + MetaClient client = new MetaClient(address, port); + client.setVersion("INVALID_VERSION"); + client.connect(); + } catch (ClientServerIncompatibleException e) { + e.printStackTrace(); + assert (true); + } catch (TException | UnknownHostException e) { + e.printStackTrace(); + assert (false); + } + } + public void testGetSpaces() { try { List spaces = metaClient.getSpaces(); diff --git a/client/src/test/java/com/vesoft/nebula/client/storage/StorageClientTest.java b/client/src/test/java/com/vesoft/nebula/client/storage/StorageClientTest.java index 780062b87..11b7e94b0 100644 --- a/client/src/test/java/com/vesoft/nebula/client/storage/StorageClientTest.java +++ b/client/src/test/java/com/vesoft/nebula/client/storage/StorageClientTest.java @@ -43,7 +43,7 @@ public void before() { assert (false); } client = new StorageClient(address); - client.setGraphAddresss(ip + ":9669"); + client.setGraphAddress(ip + ":9669"); client.setUser("root"); client.setPassword("nebula"); } @@ -55,6 +55,37 @@ public void after() { } } + @Test + public void testStorageClientWithVersionInWhiteList() { + List address = Arrays.asList(new HostAddress(ip, 9559)); + StorageClient storageClient = new StorageClient(address); + try { + storageClient.setVersion("3.0.0"); + assert (storageClient.connect()); + + storageClient.setVersion("test"); + assert (storageClient.connect()); + } catch (Exception e) { + e.printStackTrace(); + assert false; + } + } + + @Test + public void testStorageClientWithVersionNotInWhiteList() { + List address = Arrays.asList(new HostAddress(ip, 9559)); + StorageClient storageClient = new StorageClient(address); + try { + storageClient.setVersion("INVALID_VERSION"); + storageClient.connect(); + assert false; + } catch (Exception e) { + e.printStackTrace(); + assert (e.getMessage() + .contains("Current client is not compatible with the remote server")); + } + } + @Test public void testScanVertexWithNoCol() { try { diff --git a/client/src/test/resources/docker-compose.yaml b/client/src/test/resources/docker-compose.yaml index 8469173cb..def053061 100644 --- a/client/src/test/resources/docker-compose.yaml +++ b/client/src/test/resources/docker-compose.yaml @@ -16,6 +16,8 @@ services: - --minloglevel=0 - --heartbeat_interval_secs=2 - --expired_time_factor=2 + - --enable_client_white_list=true + - --client_white_list=3.0.0:test healthcheck: test: ["CMD", "curl", "-f", "http://172.28.1.1:11000/status"] interval: 30s @@ -52,6 +54,8 @@ services: - --minloglevel=0 - --heartbeat_interval_secs=2 - --expired_time_factor=2 + - --enable_client_white_list=true + - --client_white_list=3.0.0:test healthcheck: test: ["CMD", "curl", "-f", "http://172.28.1.2:11000/status"] interval: 30s @@ -88,6 +92,8 @@ services: - --minloglevel=0 - --heartbeat_interval_secs=2 - --expired_time_factor=2 + - --enable_client_white_list=true + - --client_white_list=3.0.0:test healthcheck: test: ["CMD", "curl", "-f", "http://172.28.1.3:11000/status"] interval: 30s @@ -242,6 +248,8 @@ services: - --minloglevel=0 - --heartbeat_interval_secs=2 - --timezone_name=+08:00:00 + - --enable_client_white_list=true + - --client_white_list=3.0.0:test depends_on: - metad0 - metad1 @@ -279,6 +287,8 @@ services: - --minloglevel=0 - --heartbeat_interval_secs=2 - --timezone_name=+08:00:00 + - --enable_client_white_list=true + - --client_white_list=3.0.0:test depends_on: - metad0 - metad1 @@ -316,6 +326,8 @@ services: - --minloglevel=0 - --heartbeat_interval_secs=2 - --timezone_name=+08:00:00 + - --enable_client_white_list=true + - --client_white_list=3.0.0:test depends_on: - metad0 - metad1 @@ -341,7 +353,7 @@ services: console: image: vesoft/nebula-console:nightly entrypoint: "" - command: + command: - sh - -c - | diff --git a/examples/src/main/java/com/vesoft/nebula/examples/GraphClientExample.java b/examples/src/main/java/com/vesoft/nebula/examples/GraphClientExample.java index e1bf026ac..15bab6baf 100644 --- a/examples/src/main/java/com/vesoft/nebula/examples/GraphClientExample.java +++ b/examples/src/main/java/com/vesoft/nebula/examples/GraphClientExample.java @@ -90,8 +90,11 @@ public static void main(String[] args) { try { NebulaPoolConfig nebulaPoolConfig = new NebulaPoolConfig(); nebulaPoolConfig.setMaxConnSize(100); + // optional config, default value is 3.0.0. If config other value, please make sure + // the NebulaGraph server has the same value in client_white_list + nebulaPoolConfig.setVersion("3.0.0"); List addresses = Arrays.asList(new HostAddress("127.0.0.1", 9669)); - Boolean initResult = pool.init(addresses, nebulaPoolConfig); + boolean initResult = pool.init(addresses, nebulaPoolConfig); if (!initResult) { log.error("pool init failed."); return; From 5ae33bad636e3bdb03dc583e2371fbf6801fef3d Mon Sep 17 00:00:00 2001 From: Anqi Date: Mon, 25 Dec 2023 16:09:47 +0800 Subject: [PATCH 03/14] update version --- client/pom.xml | 2 +- examples/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/pom.xml b/client/pom.xml index 08ba5119d..b02d1bd20 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -5,7 +5,7 @@ com.vesoft nebula - 3.0-SNAPSHOT + 3.7.0-zszq 4.0.0 diff --git a/examples/pom.xml b/examples/pom.xml index 0bf73b3c8..fc98cfa1e 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -5,7 +5,7 @@ com.vesoft nebula - 3.0-SNAPSHOT + 3.7.0-zszq 4.0.0 diff --git a/pom.xml b/pom.xml index 40f8b3ac2..a581b622f 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.vesoft nebula pom - 3.0-SNAPSHOT + 3.7.0-zszq UTF-8 From dc2f822e4ee855ddfe7bdfb0d3f97b1b0a2045fc Mon Sep 17 00:00:00 2001 From: Anqi Date: Tue, 26 Dec 2023 09:45:14 +0800 Subject: [PATCH 04/14] set version for scan auth (#573) --- .../java/com/vesoft/nebula/client/storage/StorageClient.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/src/main/java/com/vesoft/nebula/client/storage/StorageClient.java b/client/src/main/java/com/vesoft/nebula/client/storage/StorageClient.java index 0ba9db9c3..0ffc7e403 100644 --- a/client/src/main/java/com/vesoft/nebula/client/storage/StorageClient.java +++ b/client/src/main/java/com/vesoft/nebula/client/storage/StorageClient.java @@ -1206,7 +1206,9 @@ private void authUser() throws AuthFailedException, IOErrorException, throw new IllegalArgumentException("the graph address is invalid."); } graphConnection.open(new HostAddress(graphAddrAndPort[0].trim(), - Integer.valueOf(graphAddrAndPort[1].trim())), timeout); + Integer.valueOf(graphAddrAndPort[1].trim())), timeout, false, + new HashMap<>(), + version); AuthResult authResult = graphConnection.authenticate(user, password); long sessionId = authResult.getSessionId(); ResultSet resultSet = new ResultSet( From 5663a4d09834a1effb1d41842acc151d76efd897 Mon Sep 17 00:00:00 2001 From: Anqi Date: Fri, 29 Dec 2023 09:54:21 +0800 Subject: [PATCH 05/14] update passphrase --- .github/workflows/release.yaml | 2 +- .github/workflows/snapshot.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 67a15d2e1..e41ee099a 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -61,6 +61,6 @@ jobs: uses: samuelmeuli/action-maven-publish@v1 with: gpg_private_key: ${{ secrets.JAVA_GPG_PRIVATE_KEY }} - gpg_passphrase: ${{ secrets.JAVA_GPG_PASSPHRASE }} + gpg_passphrase: "" nexus_username: ${{ secrets.OSSRH_USERNAME }} nexus_password: ${{ secrets.OSSRH_TOKEN }} diff --git a/.github/workflows/snapshot.yaml b/.github/workflows/snapshot.yaml index 6f2009e18..f20eca198 100644 --- a/.github/workflows/snapshot.yaml +++ b/.github/workflows/snapshot.yaml @@ -62,6 +62,6 @@ jobs: uses: samuelmeuli/action-maven-publish@v1 with: gpg_private_key: ${{ secrets.JAVA_GPG_PRIVATE_KEY }} - gpg_passphrase: ${{ secrets.JAVA_GPG_PASSPHRASE }} + gpg_passphrase: "" nexus_username: ${{ secrets.OSSRH_USERNAME }} nexus_password: ${{ secrets.OSSRH_TOKEN }} From 10e6eafb87f9e325e2f0c0e9731c20cd86abb748 Mon Sep 17 00:00:00 2001 From: Anqi Date: Fri, 29 Dec 2023 14:39:57 +0800 Subject: [PATCH 06/14] add example for scan auth (#578) --- .../java/com/vesoft/nebula/examples/StorageClientExample.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/src/main/java/com/vesoft/nebula/examples/StorageClientExample.java b/examples/src/main/java/com/vesoft/nebula/examples/StorageClientExample.java index 66e1498ce..1f216ec6b 100644 --- a/examples/src/main/java/com/vesoft/nebula/examples/StorageClientExample.java +++ b/examples/src/main/java/com/vesoft/nebula/examples/StorageClientExample.java @@ -25,6 +25,10 @@ public static void main(String[] args) { // input params are the metad's ip and port StorageClient client = new StorageClient("127.0.0.1", 9559); try { + client.setGraphAddress("127.0.0.1:9669"); + client.setUser("root"); + client.setPassword("nebula"); + client.setVersion("test"); client.connect(); } catch (Exception e) { LOGGER.error("storage client connect error, ", e); From 13a0cb2704ab0b28ad403128c364b49adee64450 Mon Sep 17 00:00:00 2001 From: Anqi Date: Fri, 29 Dec 2023 15:48:12 +0800 Subject: [PATCH 07/14] process the read permission white list for root user (#579) --- .../vesoft/nebula/client/storage/StorageClient.java | 13 ++++++++++++- .../nebula/client/storage/StorageClientTest.java | 8 ++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/client/src/main/java/com/vesoft/nebula/client/storage/StorageClient.java b/client/src/main/java/com/vesoft/nebula/client/storage/StorageClient.java index 0ffc7e403..15de6304b 100644 --- a/client/src/main/java/com/vesoft/nebula/client/storage/StorageClient.java +++ b/client/src/main/java/com/vesoft/nebula/client/storage/StorageClient.java @@ -25,6 +25,7 @@ import com.vesoft.nebula.storage.ScanEdgeRequest; import com.vesoft.nebula.storage.ScanVertexRequest; import com.vesoft.nebula.storage.VertexProp; + import java.io.Serializable; import java.io.UnsupportedEncodingException; import java.util.ArrayList; @@ -34,6 +35,7 @@ import java.util.List; import java.util.Map; import java.util.Set; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -57,7 +59,7 @@ public class StorageClient implements Serializable { private String graphAddress = null; // the write list for users with read permission - private Map> spaceLabelWriteList = new HashMap<>(); + private Map> spaceLabelWriteList = null; private String version = null; /** @@ -1211,6 +1213,12 @@ private void authUser() throws AuthFailedException, IOErrorException, version); AuthResult authResult = graphConnection.authenticate(user, password); long sessionId = authResult.getSessionId(); + + if (user.equals("root")) { + return; + } + + spaceLabelWriteList = new HashMap<>(); ResultSet resultSet = new ResultSet( graphConnection.execute(sessionId, "DESC USER " + user), authResult.getTimezoneOffset()); @@ -1266,6 +1274,9 @@ private void authUser() throws AuthFailedException, IOErrorException, * @return true if spaceName and label in the WriteList */ private boolean checkWriteList(String spaceName, String label) { + if (spaceLabelWriteList == null) { + return true; + } if (!spaceLabelWriteList.containsKey(spaceName)) { return false; } diff --git a/client/src/test/java/com/vesoft/nebula/client/storage/StorageClientTest.java b/client/src/test/java/com/vesoft/nebula/client/storage/StorageClientTest.java index 11b7e94b0..0205fe29d 100644 --- a/client/src/test/java/com/vesoft/nebula/client/storage/StorageClientTest.java +++ b/client/src/test/java/com/vesoft/nebula/client/storage/StorageClientTest.java @@ -18,10 +18,12 @@ import com.vesoft.nebula.client.storage.scan.ScanVertexResult; import com.vesoft.nebula.client.storage.scan.ScanVertexResultIterator; import com.vesoft.nebula.client.util.ProcessUtil; + import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.Arrays; import java.util.List; + import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -60,6 +62,9 @@ public void testStorageClientWithVersionInWhiteList() { List address = Arrays.asList(new HostAddress(ip, 9559)); StorageClient storageClient = new StorageClient(address); try { + storageClient.setGraphAddress("127.0.0.1:9669"); + storageClient.setUser("root"); + storageClient.setPassword("nebula"); storageClient.setVersion("3.0.0"); assert (storageClient.connect()); @@ -76,6 +81,9 @@ public void testStorageClientWithVersionNotInWhiteList() { List address = Arrays.asList(new HostAddress(ip, 9559)); StorageClient storageClient = new StorageClient(address); try { + storageClient.setGraphAddress("127.0.0.1:9669"); + storageClient.setUser("root"); + storageClient.setPassword("nebula"); storageClient.setVersion("INVALID_VERSION"); storageClient.connect(); assert false; From 81b5da236348a01b43ff61f96f2615d26019ad10 Mon Sep 17 00:00:00 2001 From: Anqi Date: Fri, 29 Dec 2023 17:19:32 +0800 Subject: [PATCH 08/14] fix test --- .../com/vesoft/nebula/client/storage/StorageClient.java | 2 -- .../vesoft/nebula/client/storage/StorageClientTest.java | 9 ++++----- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/client/src/main/java/com/vesoft/nebula/client/storage/StorageClient.java b/client/src/main/java/com/vesoft/nebula/client/storage/StorageClient.java index 15de6304b..db36a1dc6 100644 --- a/client/src/main/java/com/vesoft/nebula/client/storage/StorageClient.java +++ b/client/src/main/java/com/vesoft/nebula/client/storage/StorageClient.java @@ -25,7 +25,6 @@ import com.vesoft.nebula.storage.ScanEdgeRequest; import com.vesoft.nebula.storage.ScanVertexRequest; import com.vesoft.nebula.storage.VertexProp; - import java.io.Serializable; import java.io.UnsupportedEncodingException; import java.util.ArrayList; @@ -35,7 +34,6 @@ import java.util.List; import java.util.Map; import java.util.Set; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/client/src/test/java/com/vesoft/nebula/client/storage/StorageClientTest.java b/client/src/test/java/com/vesoft/nebula/client/storage/StorageClientTest.java index 0205fe29d..8a0387581 100644 --- a/client/src/test/java/com/vesoft/nebula/client/storage/StorageClientTest.java +++ b/client/src/test/java/com/vesoft/nebula/client/storage/StorageClientTest.java @@ -8,7 +8,6 @@ import com.vesoft.nebula.client.graph.data.CASignedSSLParam; import com.vesoft.nebula.client.graph.data.HostAddress; import com.vesoft.nebula.client.graph.data.SSLParam; -import com.vesoft.nebula.client.graph.data.SelfSignedSSLParam; import com.vesoft.nebula.client.storage.data.EdgeRow; import com.vesoft.nebula.client.storage.data.EdgeTableRow; import com.vesoft.nebula.client.storage.data.VertexRow; @@ -17,13 +16,9 @@ import com.vesoft.nebula.client.storage.scan.ScanEdgeResultIterator; import com.vesoft.nebula.client.storage.scan.ScanVertexResult; import com.vesoft.nebula.client.storage.scan.ScanVertexResultIterator; -import com.vesoft.nebula.client.util.ProcessUtil; - -import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.Arrays; import java.util.List; - import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -428,6 +423,10 @@ public void testCASignedSSL() { "src/test/resources/ssl/client.crt", "src/test/resources/ssl/client.key"); sslClient = new StorageClient(address, 1000, 1, 1, true, sslParam); + sslClient.setGraphAddress("127.0.0.1:8669"); + sslClient.setUser("root"); + sslClient.setPassword("nebula"); + sslClient.setVersion("3.0.0"); sslClient.connect(); ScanVertexResultIterator resultIterator = sslClient.scanVertex( From d35bca3fa5610a134743aaa1517e8e6e2307e0f9 Mon Sep 17 00:00:00 2001 From: Anqi Date: Fri, 29 Dec 2023 17:42:59 +0800 Subject: [PATCH 09/14] add log --- .../java/com/vesoft/nebula/client/storage/StorageClientTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/client/src/test/java/com/vesoft/nebula/client/storage/StorageClientTest.java b/client/src/test/java/com/vesoft/nebula/client/storage/StorageClientTest.java index 8a0387581..95977ce38 100644 --- a/client/src/test/java/com/vesoft/nebula/client/storage/StorageClientTest.java +++ b/client/src/test/java/com/vesoft/nebula/client/storage/StorageClientTest.java @@ -434,6 +434,7 @@ public void testCASignedSSL() { "person"); assertIterator(resultIterator); } catch (Exception e) { + System.out.println("scan failed for cs ssl." + e.getMessage()); e.printStackTrace(); assert (false); } finally { From 9ed8429316709a21670662bea4b8fcd1634e4f11 Mon Sep 17 00:00:00 2001 From: George <58841610+Shinji-IkariG@users.noreply.github.com> Date: Thu, 28 Dec 2023 15:50:53 +0800 Subject: [PATCH 10/14] Update release.yaml (#575) --- .github/workflows/release.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index e41ee099a..d9e17365f 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -58,7 +58,7 @@ jobs: popd - name: Deploy Release to Maven package - uses: samuelmeuli/action-maven-publish@v1 + uses: Shinji-IkariG/action-maven-publish@v1 with: gpg_private_key: ${{ secrets.JAVA_GPG_PRIVATE_KEY }} gpg_passphrase: "" From 12ef2c87e783d6d11727a318a7906114e92aef7a Mon Sep 17 00:00:00 2001 From: George <58841610+Shinji-IkariG@users.noreply.github.com> Date: Thu, 28 Dec 2023 16:34:58 +0800 Subject: [PATCH 11/14] Revert "Update release.yaml (#575)" (#576) This reverts commit 90343ef7f6792e95a6eb660ed885860366db996a. --- .github/workflows/release.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index d9e17365f..e41ee099a 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -58,7 +58,7 @@ jobs: popd - name: Deploy Release to Maven package - uses: Shinji-IkariG/action-maven-publish@v1 + uses: samuelmeuli/action-maven-publish@v1 with: gpg_private_key: ${{ secrets.JAVA_GPG_PRIVATE_KEY }} gpg_passphrase: "" From 0dd8a3d103451363dbf427cc090f4405a1475dd3 Mon Sep 17 00:00:00 2001 From: Anqi Date: Tue, 2 Jan 2024 10:22:49 +0800 Subject: [PATCH 12/14] fix ssl --- .../nebula/client/storage/StorageClient.java | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/client/src/main/java/com/vesoft/nebula/client/storage/StorageClient.java b/client/src/main/java/com/vesoft/nebula/client/storage/StorageClient.java index db36a1dc6..90bdd80f1 100644 --- a/client/src/main/java/com/vesoft/nebula/client/storage/StorageClient.java +++ b/client/src/main/java/com/vesoft/nebula/client/storage/StorageClient.java @@ -25,6 +25,7 @@ import com.vesoft.nebula.storage.ScanEdgeRequest; import com.vesoft.nebula.storage.ScanVertexRequest; import com.vesoft.nebula.storage.VertexProp; + import java.io.Serializable; import java.io.UnsupportedEncodingException; import java.util.ArrayList; @@ -34,6 +35,7 @@ import java.util.List; import java.util.Map; import java.util.Set; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -1205,10 +1207,17 @@ private void authUser() throws AuthFailedException, IOErrorException, if (graphAddrAndPort.length != 2) { throw new IllegalArgumentException("the graph address is invalid."); } - graphConnection.open(new HostAddress(graphAddrAndPort[0].trim(), - Integer.valueOf(graphAddrAndPort[1].trim())), timeout, false, - new HashMap<>(), - version); + if (sslParam == null) { + graphConnection.open(new HostAddress(graphAddrAndPort[0].trim(), + Integer.valueOf(graphAddrAndPort[1].trim())), timeout, false, + new HashMap<>(), + version); + } else { + graphConnection.open(new HostAddress(graphAddrAndPort[0].trim(), + Integer.valueOf(graphAddrAndPort[1].trim())), timeout, sslParam, false, + new HashMap<>(), + version); + } AuthResult authResult = graphConnection.authenticate(user, password); long sessionId = authResult.getSessionId(); From 96feb752b44e42c0920b12f90888db448df2133f Mon Sep 17 00:00:00 2001 From: Anqi Date: Tue, 2 Jan 2024 10:29:03 +0800 Subject: [PATCH 13/14] fix codestyle --- .../java/com/vesoft/nebula/client/storage/StorageClient.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/client/src/main/java/com/vesoft/nebula/client/storage/StorageClient.java b/client/src/main/java/com/vesoft/nebula/client/storage/StorageClient.java index 90bdd80f1..b6cf73fd9 100644 --- a/client/src/main/java/com/vesoft/nebula/client/storage/StorageClient.java +++ b/client/src/main/java/com/vesoft/nebula/client/storage/StorageClient.java @@ -25,7 +25,6 @@ import com.vesoft.nebula.storage.ScanEdgeRequest; import com.vesoft.nebula.storage.ScanVertexRequest; import com.vesoft.nebula.storage.VertexProp; - import java.io.Serializable; import java.io.UnsupportedEncodingException; import java.util.ArrayList; @@ -35,7 +34,6 @@ import java.util.List; import java.util.Map; import java.util.Set; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; From 6307937ca1cf153d5248dddc9f65fc2d57edc5b0 Mon Sep 17 00:00:00 2001 From: Anqi Date: Wed, 3 Jan 2024 11:55:56 +0800 Subject: [PATCH 14/14] modify the client version --- client/pom.xml | 2 +- examples/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/pom.xml b/client/pom.xml index b02d1bd20..9c0b9691f 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -5,7 +5,7 @@ com.vesoft nebula - 3.7.0-zszq + 3.7.0-auth 4.0.0 diff --git a/examples/pom.xml b/examples/pom.xml index fc98cfa1e..1fdb55590 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -5,7 +5,7 @@ com.vesoft nebula - 3.7.0-zszq + 3.7.0-auth 4.0.0 diff --git a/pom.xml b/pom.xml index a581b622f..23e346e20 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.vesoft nebula pom - 3.7.0-zszq + 3.7.0-auth UTF-8