diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/SolrClientCache.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/SolrClientCache.java index 7e3abd1f84a..e544c104252 100644 --- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/SolrClientCache.java +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/SolrClientCache.java @@ -37,10 +37,10 @@ public class SolrClientCache implements Serializable { private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - private Map solrClients = new HashMap(); + private final Map solrClients = new HashMap<>(); public synchronized CloudSolrClient getCloudSolrClient(String zkHost) { - CloudSolrClient client = null; + CloudSolrClient client; if (solrClients.containsKey(zkHost)) { client = (CloudSolrClient) solrClients.get(zkHost); } else { @@ -53,7 +53,7 @@ public class SolrClientCache implements Serializable { } public synchronized HttpSolrClient getHttpSolrClient(String host) { - HttpSolrClient client = null; + HttpSolrClient client; if (solrClients.containsKey(host)) { client = (HttpSolrClient) solrClients.get(host); } else { @@ -64,12 +64,11 @@ public class SolrClientCache implements Serializable { } public void close() { - Iterator it = solrClients.values().iterator(); - while(it.hasNext()) { + for(Map.Entry entry : solrClients.entrySet()) { try { - it.next().close(); + entry.getValue().close(); } catch (IOException e) { - log.error(e.getMessage(), e); + log.error("Error closing SolrClient for " + entry.getKey(), e); } } } diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/sql/ConnectionImpl.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/sql/ConnectionImpl.java index 9f9c00ec9ec..95105c8e33f 100644 --- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/sql/ConnectionImpl.java +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/sql/ConnectionImpl.java @@ -45,17 +45,17 @@ class ConnectionImpl implements Connection { private final String url; private final SolrClientCache solrClientCache = new SolrClientCache(); private final CloudSolrClient client; - private final String collection; private final Properties properties; private final DatabaseMetaData databaseMetaData; private final Statement connectionStatement; + private String collection; private boolean closed; private SQLWarning currentWarning; ConnectionImpl(String url, String zkHost, String collection, Properties properties) throws SQLException { this.url = url; - this.client = solrClientCache.getCloudSolrClient(zkHost); - this.collection = collection; + this.client = this.solrClientCache.getCloudSolrClient(zkHost); + this.setSchema(collection); this.properties = properties; this.connectionStatement = createStatement(); this.databaseMetaData = new DatabaseMetaDataImpl(this, this.connectionStatement); @@ -158,7 +158,7 @@ class ConnectionImpl implements Connection { @Override public void setCatalog(String catalog) throws SQLException { - throw new UnsupportedOperationException(); + } @Override @@ -301,7 +301,7 @@ class ConnectionImpl implements Connection { @Override public boolean isValid(int timeout) throws SQLException { - // check that the connection isn't close and able to connect within the timeout + // check that the connection isn't closed and able to connect within the timeout try { if(!isClosed()) { this.client.connect(timeout, TimeUnit.SECONDS); @@ -345,7 +345,7 @@ class ConnectionImpl implements Connection { @Override public void setSchema(String schema) throws SQLException { - throw new UnsupportedOperationException(); + this.collection = schema; } @Override @@ -377,4 +377,4 @@ class ConnectionImpl implements Connection { public boolean isWrapperFor(Class iface) throws SQLException { throw new UnsupportedOperationException(); } -} \ No newline at end of file +} diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/sql/DatabaseMetaDataImpl.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/sql/DatabaseMetaDataImpl.java index 33cd94e94ce..62f2a1869d8 100644 --- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/sql/DatabaseMetaDataImpl.java +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/sql/DatabaseMetaDataImpl.java @@ -16,12 +16,22 @@ */ package org.apache.solr.client.solrj.io.sql; +import java.io.IOException; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.ResultSet; import java.sql.RowIdLifetime; import java.sql.SQLException; import java.sql.Statement; +import java.util.Set; + +import org.apache.solr.client.solrj.SolrClient; +import org.apache.solr.client.solrj.SolrQuery; +import org.apache.solr.client.solrj.SolrServerException; +import org.apache.solr.client.solrj.impl.CloudSolrClient; +import org.apache.solr.client.solrj.impl.HttpSolrClient; +import org.apache.solr.client.solrj.response.QueryResponse; +import org.apache.solr.common.util.SimpleOrderedMap; class DatabaseMetaDataImpl implements DatabaseMetaData { private final ConnectionImpl connection; @@ -32,6 +42,21 @@ class DatabaseMetaDataImpl implements DatabaseMetaData { this.connectionStatement = connectionStatement; } + private int getVersionPart(String version, int part) { + // TODO Is there a better way to do this? Reuse code from elsewhere? + // Gets the parts of the Solr version. If fail then just return 0. + if (version != null) { + try { + String[] versionParts = version.split("\\.", 3); + return Integer.parseInt(versionParts[part]); + } catch (Throwable e) { + return 0; + } + } else { + return 0; + } + } + @Override public boolean allProceduresAreCallable() throws SQLException { return false; @@ -79,32 +104,78 @@ class DatabaseMetaDataImpl implements DatabaseMetaData { @Override public String getDatabaseProductName() throws SQLException { - return null; + return "Apache Solr"; } @Override public String getDatabaseProductVersion() throws SQLException { - return null; + // Returns the version for the first live node in the Solr cluster. + SolrQuery sysQuery = new SolrQuery(); + sysQuery.setRequestHandler("/admin/info/system"); + + CloudSolrClient cloudSolrClient = this.connection.getClient(); + Set liveNodes = cloudSolrClient.getZkStateReader().getClusterState().getLiveNodes(); + SolrClient solrClient = null; + for (String node : liveNodes) { + try { + String nodeURL = cloudSolrClient.getZkStateReader().getBaseUrlForNodeName(node); + solrClient = new HttpSolrClient(nodeURL); + + QueryResponse rsp = solrClient.query(sysQuery); + return String.valueOf(((SimpleOrderedMap) rsp.getResponse().get("lucene")).get("solr-spec-version")); + } catch (SolrServerException | IOException ignore) { + return ""; + } finally { + if (solrClient != null) { + try { + solrClient.close(); + } catch (IOException ignore) { + // Don't worry about failing to close the Solr client + } + } + } + } + + // If no version found just return empty string + return ""; + } + + @Override + public int getDatabaseMajorVersion() throws SQLException { + return getVersionPart(this.getDatabaseProductVersion(), 0); + } + + @Override + public int getDatabaseMinorVersion() throws SQLException { + return getVersionPart(this.getDatabaseProductVersion(), 1); } @Override public String getDriverName() throws SQLException { - return null; + return this.getClass().getPackage().getSpecificationTitle(); } @Override public String getDriverVersion() throws SQLException { - return null; + return this.getClass().getPackage().getSpecificationVersion(); } @Override public int getDriverMajorVersion() { - return 0; + try { + return getVersionPart(this.getDriverVersion(), 0); + } catch (SQLException e) { + return 0; + } } @Override public int getDriverMinorVersion() { - return 0; + try { + return getVersionPart(this.getDriverVersion(), 1); + } catch (SQLException e) { + return 0; + } } @Override @@ -822,19 +893,9 @@ class DatabaseMetaDataImpl implements DatabaseMetaData { return 0; } - @Override - public int getDatabaseMajorVersion() throws SQLException { - return 0; - } - - @Override - public int getDatabaseMinorVersion() throws SQLException { - return 0; - } - @Override public int getJDBCMajorVersion() throws SQLException { - return 0; + return 4; } @Override diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/sql/JdbcTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/sql/JdbcTest.java index 82ae02e776f..ba2111404d3 100644 --- a/solr/solrj/src/test/org/apache/solr/client/solrj/io/sql/JdbcTest.java +++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/sql/JdbcTest.java @@ -381,7 +381,13 @@ public class JdbcTest extends AbstractFullDistribZkTestBase { private void testJDBCMethods(String collection, String connectionString, Properties properties, String sql) throws Exception { try (Connection con = DriverManager.getConnection(connectionString, properties)) { assertTrue(con.isValid(DEFAULT_CONNECTION_TIMEOUT)); + assertEquals(zkServer.getZkAddress(), con.getCatalog()); + con.setCatalog(zkServer.getZkAddress()); + assertEquals(zkServer.getZkAddress(), con.getCatalog()); + + assertEquals(collection, con.getSchema()); + con.setSchema(collection); assertEquals(collection, con.getSchema()); DatabaseMetaData databaseMetaData = con.getMetaData(); @@ -390,6 +396,21 @@ public class JdbcTest extends AbstractFullDistribZkTestBase { assertEquals(con, databaseMetaData.getConnection()); assertEquals(connectionString, databaseMetaData.getURL()); + assertEquals(4, databaseMetaData.getJDBCMajorVersion()); + assertEquals(0, databaseMetaData.getJDBCMinorVersion()); + + assertEquals("Apache Solr", databaseMetaData.getDatabaseProductName()); + + // The following tests require package information that is not available when running via Maven +// assertEquals(this.getClass().getPackage().getSpecificationVersion(), databaseMetaData.getDatabaseProductVersion()); +// assertEquals(0, databaseMetaData.getDatabaseMajorVersion()); +// assertEquals(0, databaseMetaData.getDatabaseMinorVersion()); + +// assertEquals(this.getClass().getPackage().getSpecificationTitle(), databaseMetaData.getDriverName()); +// assertEquals(this.getClass().getPackage().getSpecificationVersion(), databaseMetaData.getDriverVersion()); +// assertEquals(0, databaseMetaData.getDriverMajorVersion()); +// assertEquals(0, databaseMetaData.getDriverMinorVersion()); + try(ResultSet rs = databaseMetaData.getCatalogs()) { assertTrue(rs.next()); assertEquals(zkServer.getZkAddress(), rs.getString("TABLE_CAT"));