提交 4b204d0b authored 作者: noelgrandin@gmail.com's avatar noelgrandin@gmail.com

Add client-info property to get the number of servers currently in the cluster

and which servers that are available. (patch from  Nikolaj Fogh) 
上级 b33f7212
...@@ -390,6 +390,15 @@ If the result is <code>''</code> (two single quotes), then the cluster mode is d ...@@ -390,6 +390,15 @@ If the result is <code>''</code> (two single quotes), then the cluster mode is d
servers is returned, enclosed in single quote. Example: <code>'server1:9191,server2:9191'</code>. servers is returned, enclosed in single quote. Example: <code>'server1:9191,server2:9191'</code>.
</p> </p>
<p>It is also possible to get the list of servers by using Connection.getClientInfo().</p>
<p>The property list returned from <code>getClientInfo()</code> contains a <code>numServers</code> property that returns the
number of servers that are in the connection list. To get the actual servers, <code>getClientInfo()</code> also has
properties <code>server0</code>..<code>serverX</code>, where serverX is the number of servers minus 1.
<p>Example: To get the 2nd server in the connection list one uses <code>getClientInfo('server1')<code>. <b>Note:</b> The
<code>serverX</code> property only returns IP addresses and ports and not hostnames.</p>
<h3>Clustering Algorithm and Limitations</h3> <h3>Clustering Algorithm and Limitations</h3>
<p> <p>
Read-only queries are only executed against the first cluster node, but all other statements are Read-only queries are only executed against the first cluster node, but all other statements are
......
...@@ -19,6 +19,8 @@ Change Log ...@@ -19,6 +19,8 @@ Change Log
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul><li>The LIRS cache now re-sizes the internal hash map if needed. <ul><li>The LIRS cache now re-sizes the internal hash map if needed.
<ul><li>Optionally persist session history in the H2 console. (patch from Martin Grajcar) <ul><li>Optionally persist session history in the H2 console. (patch from Martin Grajcar)
<ul><li>Add client-info property to get the number of servers currently in the cluster
and which servers that are available. (patch from Nikolaj Fogh)
</li></ul> </li></ul>
<h2>Version 1.4.179 Beta (2014-06-23)</h2> <h2>Version 1.4.179 Beta (2014-06-23)</h2>
......
...@@ -127,6 +127,10 @@ public class Session extends SessionWithState { ...@@ -127,6 +127,10 @@ public class Session extends SessionWithState {
this.currentSchemaName = Constants.SCHEMA_MAIN; this.currentSchemaName = Constants.SCHEMA_MAIN;
} }
public ArrayList<String> getClusterServers() {
return new ArrayList<String>();
}
public boolean setCommitOrRollbackDisabled(boolean x) { public boolean setCommitOrRollbackDisabled(boolean x) {
boolean old = commitOrRollbackDisabled; boolean old = commitOrRollbackDisabled;
commitOrRollbackDisabled = x; commitOrRollbackDisabled = x;
......
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
package org.h2.engine; package org.h2.engine;
import java.io.Closeable; import java.io.Closeable;
import java.util.ArrayList;
import org.h2.command.CommandInterface; import org.h2.command.CommandInterface;
import org.h2.message.Trace; import org.h2.message.Trace;
import org.h2.store.DataHandler; import org.h2.store.DataHandler;
...@@ -16,6 +18,13 @@ import org.h2.value.Value; ...@@ -16,6 +18,13 @@ import org.h2.value.Value;
*/ */
public interface SessionInterface extends Closeable { public interface SessionInterface extends Closeable {
/**
* Get the list of the cluster servers for this session.
*
* @return A list of "IP:PORT" strings for the cluster servers in this session.
*/
ArrayList<String> getClusterServers();
/** /**
* Parse a command and prepare it for execution. * Parse a command and prepare it for execution.
* *
......
...@@ -95,6 +95,15 @@ public class SessionRemote extends SessionWithState implements DataHandler { ...@@ -95,6 +95,15 @@ public class SessionRemote extends SessionWithState implements DataHandler {
this.connectionInfo = ci; this.connectionInfo = ci;
} }
public ArrayList<String> getClusterServers() {
ArrayList<String> serverList = new ArrayList<String>();
for (int i = 0; i < transferList.size(); i++) {
Transfer transfer = transferList.get(i);
serverList.add(transfer.getSocket().getInetAddress().getHostAddress().toString() + ":" + String.valueOf(transfer.getSocket().getPort()));
}
return serverList;
}
private Transfer initTransfer(ConnectionInfo ci, String db, String server) private Transfer initTransfer(ConnectionInfo ci, String db, String server)
throws IOException { throws IOException {
Socket socket = NetUtils.createSocket(server, Socket socket = NetUtils.createSocket(server,
......
...@@ -25,6 +25,7 @@ import java.sql.SQLXML; ...@@ -25,6 +25,7 @@ import java.sql.SQLXML;
import java.sql.Savepoint; import java.sql.Savepoint;
import java.sql.Statement; import java.sql.Statement;
import java.sql.Struct; import java.sql.Struct;
import java.util.ArrayList;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
...@@ -1715,35 +1716,44 @@ public class JdbcConnection extends TraceObject implements Connection { ...@@ -1715,35 +1716,44 @@ public class JdbcConnection extends TraceObject implements Connection {
/** /**
* Get the client properties. * Get the client properties.
* This method always returns null.
* *
* @return always null * @return the property list
*/ */
@Override @Override
public Properties getClientInfo() throws SQLException { public Properties getClientInfo() throws SQLException {
try { try {
if (isDebugEnabled()) {
debugCode("getClientInfo();"); debugCode("getClientInfo();");
// we don't have any client properties, so return null }
return null; checkClosed();
ArrayList<String> serverList = session.getClusterServers();
Properties p = new Properties();
p.setProperty("numServers", String.valueOf(serverList.size()));
for (int i = 0; i < serverList.size(); i++) {
p.setProperty("server" + String.valueOf(i), serverList.get(i));
}
return p;
} catch (Exception e) { } catch (Exception e) {
throw logAndConvert(e); throw logAndConvert(e);
} }
} }
/** /**
* Set a client property. * Get a client property.
* This method always throws a SQLClientInfoException.
* *
* @param name the client info name (ignored) * @param name the client info name (ignored)
* @return this method never returns normally * @return the property value
*/ */
@Override @Override
public String getClientInfo(String name) throws SQLException { public String getClientInfo(String name) throws SQLException {
try { try {
if (isDebugEnabled()) {
debugCodeCall("getClientInfo", name); debugCodeCall("getClientInfo", name);
}
checkClosed(); checkClosed();
// we don't have any client properties, so just throw Properties p = getClientInfo();
throw new SQLClientInfoException(); return p.getProperty(name);
} catch (Exception e) { } catch (Exception e) {
throw logAndConvert(e); throw logAndConvert(e);
} }
......
...@@ -10,6 +10,7 @@ import java.sql.PreparedStatement; ...@@ -10,6 +10,7 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.Properties;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.store.fs.FileUtils; import org.h2.store.fs.FileUtils;
...@@ -39,6 +40,7 @@ public class TestCluster extends TestBase { ...@@ -39,6 +40,7 @@ public class TestCluster extends TestBase {
testRecover(); testRecover();
testRollback(); testRollback();
testCase(); testCase();
testClientInfo();
testCreateClusterAtRuntime(); testCreateClusterAtRuntime();
testStartStopCluster(); testStartStopCluster();
} }
...@@ -250,6 +252,60 @@ public class TestCluster extends TestBase { ...@@ -250,6 +252,60 @@ public class TestCluster extends TestBase {
n1.stop(); n1.stop();
deleteFiles(); deleteFiles();
} }
private void testClientInfo() throws SQLException {
if (config.memory || config.networked || config.cipher != null) {
return;
}
int port1 = 9191, port2 = 9192;
String serverList = "localhost:" + port1 + ",localhost:" + port2;
deleteFiles();
org.h2.Driver.load();
String user = getUser(), password = getPassword();
Connection conn;
String url1 = getURL("jdbc:h2:tcp://localhost:" + port1 + "/test", true);
String url2 = getURL("jdbc:h2:tcp://localhost:" + port2 + "/test", true);
String urlCluster = getURL("jdbc:h2:tcp://" + serverList + "/test", true);
Server n1 = org.h2.tools.Server.createTcpServer("-tcpPort",
"" + port1, "-baseDir", getBaseDir() + "/node1").start();
Server n2 = org.h2.tools.Server.createTcpServer("-tcpPort",
"" + port2 , "-baseDir", getBaseDir() + "/node2").start();
CreateCluster.main("-urlSource", url1, "-urlTarget", url2,
"-user", user, "-password", password, "-serverList",
serverList);
conn = getConnection(urlCluster, user, password);
Properties p = conn.getClientInfo();
assertEquals("2", p.getProperty("numServers"));
assertEquals("127.0.0.1:" + port1, p.getProperty("server0"));
assertEquals("127.0.0.1:" + port2, p.getProperty("server1"));
assertEquals("2", conn.getClientInfo("numServers"));
assertEquals("127.0.0.1:" + port1, conn.getClientInfo("server0"));
assertEquals("127.0.0.1:" + port2, conn.getClientInfo("server1"));
conn.close();
// stop server 2, and test if only one server is available
n2.stop();
conn = getConnection(urlCluster, user, password);
p = conn.getClientInfo();
assertEquals("1", p.getProperty("numServers"));
assertEquals("127.0.0.1:" + port1, p.getProperty("server0"));
assertEquals("1", conn.getClientInfo("numServers"));
assertEquals("127.0.0.1:" + port1, conn.getClientInfo("server0"));
conn.close();
n1.stop();
deleteFiles();
}
private void testCreateClusterAtRuntime() throws SQLException { private void testCreateClusterAtRuntime() throws SQLException {
if (config.memory || config.networked || config.cipher != null) { if (config.memory || config.networked || config.cipher != null) {
return; return;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论