You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by el...@apache.org on 2017/04/01 20:36:14 UTC
[22/51] [partial] calcite-avatica git commit: [CALCITE-1717] Remove
Calcite code and lift avatica
http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/fc7b26c8/avatica/server/src/test/java/org/apache/calcite/avatica/SpnegoTestUtil.java
----------------------------------------------------------------------
diff --git a/avatica/server/src/test/java/org/apache/calcite/avatica/SpnegoTestUtil.java b/avatica/server/src/test/java/org/apache/calcite/avatica/SpnegoTestUtil.java
deleted file mode 100644
index ab4491d..0000000
--- a/avatica/server/src/test/java/org/apache/calcite/avatica/SpnegoTestUtil.java
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to you under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.calcite.avatica;
-
-import org.apache.calcite.avatica.remote.Service.RpcMetadataResponse;
-import org.apache.calcite.avatica.server.AvaticaHandler;
-
-import org.apache.kerby.kerberos.kerb.KrbException;
-import org.apache.kerby.kerberos.kerb.server.SimpleKdcServer;
-
-import org.eclipse.jetty.security.UserAuthentication;
-import org.eclipse.jetty.server.Authentication;
-import org.eclipse.jetty.server.Handler;
-import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.UserIdentity;
-import org.eclipse.jetty.server.handler.DefaultHandler;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.net.ServerSocket;
-import java.nio.charset.StandardCharsets;
-import java.security.AccessController;
-import java.security.Principal;
-import java.security.PrivilegedAction;
-
-import javax.security.auth.login.Configuration;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-/**
- * Utility class for setting up SPNEGO
- */
-public class SpnegoTestUtil {
-
- public static final String JGSS_KERBEROS_TICKET_OID = "1.2.840.113554.1.2.2";
-
- public static final String REALM = "EXAMPLE.COM";
- public static final String KDC_HOST = "localhost";
- public static final String CLIENT_PRINCIPAL = "client@" + REALM;
- public static final String SERVER_PRINCIPAL = "HTTP/" + KDC_HOST + "@" + REALM;
-
- private SpnegoTestUtil() {}
-
- public static int getFreePort() throws IOException {
- ServerSocket s = new ServerSocket(0);
- try {
- s.setReuseAddress(true);
- int port = s.getLocalPort();
- return port;
- } finally {
- if (null != s) {
- s.close();
- }
- }
- }
-
- public static void setupUser(SimpleKdcServer kdc, File keytab, String principal)
- throws KrbException {
- kdc.createPrincipal(principal);
- kdc.exportPrincipal(principal, keytab);
- }
-
- /**
- * Recursively deletes a {@link File}.
- */
- public static void deleteRecursively(File d) {
- if (d.isDirectory()) {
- for (String name : d.list()) {
- File child = new File(d, name);
- if (child.isFile()) {
- child.delete();
- } else {
- deleteRecursively(d);
- }
- }
- }
- d.delete();
- }
-
- /**
- * Creates the SPNEGO JAAS configuration file for the Jetty server
- */
- public static void writeSpnegoConf(File configFile, File serverKeytab)
- throws Exception {
- try (BufferedWriter writer =
- new BufferedWriter(
- new OutputStreamWriter(
- new FileOutputStream(configFile),
- StandardCharsets.UTF_8))) {
- // Server login
- writer.write("com.sun.security.jgss.accept {\n");
- writer.write(" com.sun.security.auth.module.Krb5LoginModule required\n");
- writer.write(" principal=\"" + SERVER_PRINCIPAL + "\"\n");
- writer.write(" useKeyTab=true\n");
- writer.write(" keyTab=\"" + serverKeytab.toURI() + "\"\n");
- writer.write(" storeKey=true \n");
- // Some extra debug information from JAAS
- //writer.write(" debug=true\n");
- writer.write(" isInitiator=false;\n");
- writer.write("};\n");
- }
- }
-
- public static void refreshJaasConfiguration() {
- // This is *extremely* important to make sure we get the right Configuration instance.
- // Configuration keeps a static instance of Configuration that it will return once it
- // has been initialized. We need to nuke that static instance to make sure our
- // serverSpnegoConfigFile gets read.
- AccessController.doPrivileged(new PrivilegedAction<Configuration>() {
- public Configuration run() {
- return Configuration.getConfiguration();
- }
- }).refresh();
- }
-
- /**
- * A simple handler which returns "OK " with the client's authenticated name and HTTP/200 or
- * HTTP/401 and the message "Not authenticated!".
- */
- public static class AuthenticationRequiredAvaticaHandler implements AvaticaHandler {
- private final Handler handler = new DefaultHandler();
-
- @Override public void handle(String target, Request baseRequest, HttpServletRequest request,
- HttpServletResponse response) throws IOException, ServletException {
- Authentication auth = baseRequest.getAuthentication();
- if (Authentication.UNAUTHENTICATED == auth) {
- throw new AssertionError("Unauthenticated users should not reach here!");
- }
-
- baseRequest.setHandled(true);
- UserAuthentication userAuth = (UserAuthentication) auth;
- UserIdentity userIdentity = userAuth.getUserIdentity();
- Principal userPrincipal = userIdentity.getUserPrincipal();
-
- response.getWriter().print("OK " + userPrincipal.getName());
- response.setStatus(200);
- }
-
- @Override public void setServer(Server server) {
- handler.setServer(server);
- }
-
- @Override public Server getServer() {
- return handler.getServer();
- }
-
- @Override public void destroy() {
- handler.destroy();
- }
-
- @Override public void start() throws Exception {
- handler.start();
- }
-
- @Override public void stop() throws Exception {
- handler.stop();
- }
-
- @Override public boolean isRunning() {
- return handler.isRunning();
- }
-
- @Override public boolean isStarted() {
- return handler.isStarted();
- }
-
- @Override public boolean isStarting() {
- return handler.isStarting();
- }
-
- @Override public boolean isStopping() {
- return handler.isStopping();
- }
-
- @Override public boolean isStopped() {
- return handler.isStopped();
- }
-
- @Override public boolean isFailed() {
- return handler.isFailed();
- }
-
- @Override public void addLifeCycleListener(Listener listener) {
- handler.addLifeCycleListener(listener);
- }
-
- @Override public void removeLifeCycleListener(Listener listener) {
- handler.removeLifeCycleListener(listener);
- }
-
- @Override public void setServerRpcMetadata(RpcMetadataResponse metadata) {}
- }
-}
-
-// End SpnegoTestUtil.java
http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/fc7b26c8/avatica/server/src/test/java/org/apache/calcite/avatica/SslDriverTest.java
----------------------------------------------------------------------
diff --git a/avatica/server/src/test/java/org/apache/calcite/avatica/SslDriverTest.java b/avatica/server/src/test/java/org/apache/calcite/avatica/SslDriverTest.java
deleted file mode 100644
index e3b89f5..0000000
--- a/avatica/server/src/test/java/org/apache/calcite/avatica/SslDriverTest.java
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to you under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.calcite.avatica;
-
-import org.apache.calcite.avatica.jdbc.JdbcMeta;
-import org.apache.calcite.avatica.remote.Driver;
-import org.apache.calcite.avatica.remote.LocalService;
-import org.apache.calcite.avatica.server.HttpServer;
-import org.apache.calcite.avatica.util.DateTimeUtils;
-
-import org.bouncycastle.asn1.x500.X500Name;
-import org.bouncycastle.asn1.x500.style.IETFUtils;
-import org.bouncycastle.asn1.x500.style.RFC4519Style;
-import org.bouncycastle.asn1.x509.BasicConstraints;
-import org.bouncycastle.asn1.x509.Extension;
-import org.bouncycastle.asn1.x509.KeyUsage;
-import org.bouncycastle.cert.CertIOException;
-import org.bouncycastle.cert.X509CertificateHolder;
-import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils;
-import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
-import org.bouncycastle.jce.provider.X509CertificateObject;
-import org.bouncycastle.operator.OperatorCreationException;
-import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
-import org.junit.AfterClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.math.BigInteger;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.KeyStore;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.Security;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateException;
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.ResultSet;
-import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.List;
-import java.util.Objects;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-/**
- * Test case for Avatica with TLS connectors.
- */
-@RunWith(Parameterized.class)
-public class SslDriverTest {
- private static final Logger LOG = LoggerFactory.getLogger(SslDriverTest.class);
-
- private static File keystore;
- private static final String KEYSTORE_PASSWORD = "avaticasecret";
- private static final ConnectionSpec CONNECTION_SPEC = ConnectionSpec.HSQLDB;
- private static final List<HttpServer> SERVERS_TO_STOP = new ArrayList<>();
-
- @Parameters public static List<Object[]> parameters() throws Exception {
- final ArrayList<Object[]> parameters = new ArrayList<>();
-
- // Create a self-signed cert
- File target = new File(System.getProperty("user.dir"), "target");
- keystore = new File(target, "avatica-test.jks");
- if (keystore.isFile()) {
- assertTrue("Failed to delete keystore: " + keystore, keystore.delete());
- }
- new CertTool().createSelfSignedCert(keystore, "avatica", KEYSTORE_PASSWORD);
-
- // Create a LocalService around HSQLDB
- final JdbcMeta jdbcMeta = new JdbcMeta(CONNECTION_SPEC.url,
- CONNECTION_SPEC.username, CONNECTION_SPEC.password);
- final LocalService localService = new LocalService(jdbcMeta);
-
- for (Driver.Serialization serialization : new Driver.Serialization[] {
- Driver.Serialization.JSON, Driver.Serialization.PROTOBUF}) {
- // Build and start the server, using TLS
- HttpServer httpServer = new HttpServer.Builder()
- .withPort(0)
- .withTLS(keystore, KEYSTORE_PASSWORD, keystore, KEYSTORE_PASSWORD)
- .withHandler(localService, serialization)
- .build();
- httpServer.start();
- SERVERS_TO_STOP.add(httpServer);
-
- final String url = "jdbc:avatica:remote:url=https://localhost:" + httpServer.getPort()
- + ";serialization=" + serialization + ";truststore=" + keystore.getAbsolutePath()
- + ";truststore_password=" + KEYSTORE_PASSWORD;
- LOG.info("JDBC URL {}", url);
-
- parameters.add(new Object[] {url});
- }
-
- return parameters;
- }
-
- @AfterClass public static void stopKdc() throws Exception {
- for (HttpServer server : SERVERS_TO_STOP) {
- server.stop();
- }
- }
-
- private final String jdbcUrl;
-
- public SslDriverTest(String jdbcUrl) {
- this.jdbcUrl = Objects.requireNonNull(jdbcUrl);
- }
-
- @Test
- public void testReadWrite() throws Exception {
- final String tableName = "testReadWrite";
- try (Connection conn = DriverManager.getConnection(jdbcUrl);
- Statement stmt = conn.createStatement()) {
- assertFalse(stmt.execute("DROP TABLE IF EXISTS " + tableName));
- assertFalse(stmt.execute("CREATE TABLE " + tableName + "(pk integer)"));
- assertEquals(1, stmt.executeUpdate("INSERT INTO " + tableName + " VALUES(1)"));
- assertEquals(1, stmt.executeUpdate("INSERT INTO " + tableName + " VALUES(2)"));
- assertEquals(1, stmt.executeUpdate("INSERT INTO " + tableName + " VALUES(3)"));
-
- ResultSet results = stmt.executeQuery("SELECT count(1) FROM " + tableName);
- assertTrue(results.next());
- assertEquals(3, results.getInt(1));
- }
- }
-
- /**
- * Utility class for creating certificates for testing.
- */
- private static class CertTool {
- private static final String SIGNING_ALGORITHM = "SHA256WITHRSA";
- private static final String ENC_ALGORITHM = "RSA";
-
- static {
- Security.addProvider(new BouncyCastleProvider());
- }
-
- private void createSelfSignedCert(File targetKeystore, String keyName,
- String keystorePassword) {
- if (targetKeystore.exists()) {
- throw new RuntimeException("Keystore already exists: " + targetKeystore);
- }
-
- try {
- KeyPair kp = generateKeyPair();
-
- X509CertificateObject cert = generateCert(keyName, kp, true, kp.getPublic(),
- kp.getPrivate());
-
- char[] password = keystorePassword.toCharArray();
- KeyStore keystore = KeyStore.getInstance("JKS");
- keystore.load(null, null);
- keystore.setCertificateEntry(keyName + "Cert", cert);
- keystore.setKeyEntry(keyName + "Key", kp.getPrivate(), password, new Certificate[] {cert});
- try (FileOutputStream fos = new FileOutputStream(targetKeystore)) {
- keystore.store(fos, password);
- }
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- private KeyPair generateKeyPair() throws NoSuchAlgorithmException, NoSuchProviderException {
- KeyPairGenerator gen = KeyPairGenerator.getInstance(ENC_ALGORITHM);
- gen.initialize(2048);
- return gen.generateKeyPair();
- }
-
- private X509CertificateObject generateCert(String keyName, KeyPair kp, boolean isCertAuthority,
- PublicKey signerPublicKey, PrivateKey signerPrivateKey) throws IOException,
- CertIOException, OperatorCreationException, CertificateException,
- NoSuchAlgorithmException {
- Calendar startDate = DateTimeUtils.calendar();
- Calendar endDate = DateTimeUtils.calendar();
- endDate.add(Calendar.YEAR, 100);
-
- BigInteger serialNumber = BigInteger.valueOf(startDate.getTimeInMillis());
- X500Name issuer = new X500Name(
- IETFUtils.rDNsFromString("cn=localhost", RFC4519Style.INSTANCE));
- JcaX509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(issuer,
- serialNumber, startDate.getTime(), endDate.getTime(), issuer, kp.getPublic());
- JcaX509ExtensionUtils extensionUtils = new JcaX509ExtensionUtils();
- certGen.addExtension(Extension.subjectKeyIdentifier, false,
- extensionUtils.createSubjectKeyIdentifier(kp.getPublic()));
- certGen.addExtension(Extension.basicConstraints, false,
- new BasicConstraints(isCertAuthority));
- certGen.addExtension(Extension.authorityKeyIdentifier, false,
- extensionUtils.createAuthorityKeyIdentifier(signerPublicKey));
- if (isCertAuthority) {
- certGen.addExtension(Extension.keyUsage, true, new KeyUsage(KeyUsage.keyCertSign));
- }
- X509CertificateHolder cert = certGen.build(
- new JcaContentSignerBuilder(SIGNING_ALGORITHM).build(signerPrivateKey));
- return new X509CertificateObject(cert.toASN1Structure());
- }
- }
-}
-
-// End SslDriverTest.java
http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/fc7b26c8/avatica/server/src/test/java/org/apache/calcite/avatica/jdbc/JdbcMetaTest.java
----------------------------------------------------------------------
diff --git a/avatica/server/src/test/java/org/apache/calcite/avatica/jdbc/JdbcMetaTest.java b/avatica/server/src/test/java/org/apache/calcite/avatica/jdbc/JdbcMetaTest.java
deleted file mode 100644
index d84fd29..0000000
--- a/avatica/server/src/test/java/org/apache/calcite/avatica/jdbc/JdbcMetaTest.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to you under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.calcite.avatica.jdbc;
-
-import org.apache.calcite.avatica.AvaticaPreparedStatement;
-import org.apache.calcite.avatica.Meta.ConnectionHandle;
-import org.apache.calcite.avatica.Meta.Signature;
-import org.apache.calcite.avatica.Meta.StatementHandle;
-
-import com.google.common.cache.Cache;
-
-import org.junit.Test;
-import org.mockito.Mockito;
-
-import java.sql.Connection;
-import java.sql.ParameterMetaData;
-import java.sql.PreparedStatement;
-import java.sql.ResultSetMetaData;
-import java.sql.SQLException;
-import java.util.UUID;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.fail;
-
-/**
- * Unit tests for {@link JdbcMeta}.
- */
-public class JdbcMetaTest {
-
- @Test public void testExceptionPropagation() throws SQLException {
- JdbcMeta meta = new JdbcMeta("url");
- final Throwable e = new Exception();
- final RuntimeException rte;
- try {
- meta.propagate(e);
- fail("Expected an exception to be thrown");
- } catch (RuntimeException caughtException) {
- rte = caughtException;
- assertThat(rte.getCause(), is(e));
- }
- }
-
- @Test public void testPrepareSetsMaxRows() throws Exception {
- final String id = UUID.randomUUID().toString();
- final String sql = "SELECT * FROM FOO";
- final int maxRows = 500;
- final ConnectionHandle ch = new ConnectionHandle(id);
- final AtomicInteger statementIdGenerator = new AtomicInteger(0);
-
- JdbcMeta meta = Mockito.mock(JdbcMeta.class);
- Connection connection = Mockito.mock(Connection.class);
- PreparedStatement statement = Mockito.mock(PreparedStatement.class);
- ResultSetMetaData resultSetMetaData = Mockito.mock(ResultSetMetaData.class);
- ParameterMetaData parameterMetaData = Mockito.mock(ParameterMetaData.class);
- @SuppressWarnings("unchecked")
- Cache<Integer, StatementInfo> statementCache =
- (Cache<Integer, StatementInfo>) Mockito.mock(Cache.class);
-
- Mockito.when(meta.getStatementIdGenerator()).thenReturn(statementIdGenerator);
- Mockito.when(meta.getStatementCache()).thenReturn(statementCache);
- Mockito.when(meta.getConnection(id)).thenReturn(connection);
- Mockito.when(connection.prepareStatement(sql)).thenReturn(statement);
- Mockito.when(statement.isWrapperFor(AvaticaPreparedStatement.class)).thenReturn(false);
- Mockito.when(statement.getMetaData()).thenReturn(resultSetMetaData);
- Mockito.when(statement.getParameterMetaData()).thenReturn(parameterMetaData);
- // Call the real methods
- Mockito.doCallRealMethod().when(meta).setMaxRows(statement, maxRows);
- Mockito.doCallRealMethod().when(meta).prepare(ch, sql, maxRows);
-
- meta.prepare(ch, sql, maxRows);
-
- Mockito.verify(statement).setMaxRows(maxRows);
- }
-
- @Test public void testPrepareAndExecuteSetsMaxRows() throws Exception {
- final String id = UUID.randomUUID().toString();
- final int statementId = 12345;
- final String sql = "SELECT * FROM FOO";
- final int maxRows = 500;
-
- JdbcMeta meta = Mockito.mock(JdbcMeta.class);
- PreparedStatement statement = Mockito.mock(PreparedStatement.class);
- @SuppressWarnings("unchecked")
- Cache<Integer, StatementInfo> statementCache =
- (Cache<Integer, StatementInfo>) Mockito.mock(Cache.class);
- Signature signature = Mockito.mock(Signature.class);
-
- final StatementInfo statementInfo = new StatementInfo(statement);
- final StatementHandle statementHandle = new StatementHandle(id, statementId, signature);
-
- Mockito.when(meta.getStatementCache()).thenReturn(statementCache);
- Mockito.when(statementCache.getIfPresent(statementId)).thenReturn(statementInfo);
- Mockito.when(statement.getResultSet()).thenReturn(null);
- // The real methods
- Mockito.when(meta.prepareAndExecute(statementHandle, sql, maxRows, 50, null)).
- thenCallRealMethod();
- Mockito.doCallRealMethod().when(meta).setMaxRows(statement, maxRows);
-
- // Call our method
- meta.prepareAndExecute(statementHandle, sql, maxRows, 50, null);
-
- // Verify we called setMaxRows with the right value
- Mockito.verify(statement).setMaxRows(maxRows);
- }
-}
-
-// End JdbcMetaTest.java
http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/fc7b26c8/avatica/server/src/test/java/org/apache/calcite/avatica/jdbc/StatementInfoTest.java
----------------------------------------------------------------------
diff --git a/avatica/server/src/test/java/org/apache/calcite/avatica/jdbc/StatementInfoTest.java b/avatica/server/src/test/java/org/apache/calcite/avatica/jdbc/StatementInfoTest.java
deleted file mode 100644
index 2984692..0000000
--- a/avatica/server/src/test/java/org/apache/calcite/avatica/jdbc/StatementInfoTest.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to you under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.calcite.avatica.jdbc;
-
-import org.junit.Test;
-import org.mockito.InOrder;
-import org.mockito.Mockito;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-
-import java.sql.ResultSet;
-import java.sql.SQLFeatureNotSupportedException;
-import java.sql.Statement;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-/**
- * Tests covering {@link StatementInfo}.
- */
-public class StatementInfoTest {
-
- @Test
- public void testLargeOffsets() throws Exception {
- Statement stmt = Mockito.mock(Statement.class);
- ResultSet results = Mockito.mock(ResultSet.class);
-
- StatementInfo info = new StatementInfo(stmt);
-
- Mockito.when(results.relative(Integer.MAX_VALUE)).thenReturn(true, true);
- Mockito.when(results.relative(1)).thenReturn(true);
-
- long offset = 1L + Integer.MAX_VALUE + Integer.MAX_VALUE;
- assertTrue(info.advanceResultSetToOffset(results, offset));
-
- InOrder inOrder = Mockito.inOrder(results);
-
- inOrder.verify(results, Mockito.times(2)).relative(Integer.MAX_VALUE);
- inOrder.verify(results).relative(1);
-
- assertEquals(offset, info.getPosition());
- }
-
- @Test
- public void testNextUpdatesPosition() throws Exception {
- Statement stmt = Mockito.mock(Statement.class);
- ResultSet results = Mockito.mock(ResultSet.class);
-
- StatementInfo info = new StatementInfo(stmt);
- info.setResultSet(results);
-
- Mockito.when(results.next()).thenReturn(true, true, true, false);
-
- for (int i = 0; i < 3; i++) {
- assertTrue(i + "th call of next() should return true", info.next());
- assertEquals(info.getPosition(), i + 1);
- }
-
- assertFalse("Expected last next() to return false", info.next());
- assertEquals(info.getPosition(), 4L);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testNoMovement() throws Exception {
- Statement stmt = Mockito.mock(Statement.class);
- ResultSet results = Mockito.mock(ResultSet.class);
-
- StatementInfo info = new StatementInfo(stmt);
- info.setPosition(500);
-
- info.advanceResultSetToOffset(results, 400);
- }
-
- @Test public void testResultSetGetter() throws Exception {
- Statement stmt = Mockito.mock(Statement.class);
- ResultSet results = Mockito.mock(ResultSet.class);
-
- StatementInfo info = new StatementInfo(stmt);
-
- assertFalse("ResultSet should not be initialized", info.isResultSetInitialized());
- assertNull("ResultSet should be null", info.getResultSet());
-
- info.setResultSet(results);
-
- assertTrue("ResultSet should be initialized", info.isResultSetInitialized());
- assertEquals(results, info.getResultSet());
- }
-
- @Test public void testCheckPositionAfterFailedRelative() throws Exception {
- Statement stmt = Mockito.mock(Statement.class);
- ResultSet results = Mockito.mock(ResultSet.class);
- final long offset = 500;
-
- StatementInfo info = new StatementInfo(stmt);
- info.setResultSet(results);
-
- // relative() doesn't work
- Mockito.when(results.relative((int) offset)).thenThrow(new SQLFeatureNotSupportedException());
- // Should fall back to next(), 500 calls to next, 1 false
- Mockito.when(results.next()).then(new Answer<Boolean>() {
- private long invocations = 0;
-
- // Return true until 500, false after.
- @Override public Boolean answer(InvocationOnMock invocation) throws Throwable {
- invocations++;
- if (invocations >= offset) {
- return false;
- }
- return true;
- }
- });
-
- info.advanceResultSetToOffset(results, offset);
-
- // Verify correct position
- assertEquals(offset, info.getPosition());
- // Make sure that we actually advanced the result set
- Mockito.verify(results, Mockito.times(500)).next();
- }
-}
-
-// End StatementInfoTest.java
http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/fc7b26c8/avatica/server/src/test/java/org/apache/calcite/avatica/remote/AlternatingRemoteMetaTest.java
----------------------------------------------------------------------
diff --git a/avatica/server/src/test/java/org/apache/calcite/avatica/remote/AlternatingRemoteMetaTest.java b/avatica/server/src/test/java/org/apache/calcite/avatica/remote/AlternatingRemoteMetaTest.java
deleted file mode 100644
index d0c10c6..0000000
--- a/avatica/server/src/test/java/org/apache/calcite/avatica/remote/AlternatingRemoteMetaTest.java
+++ /dev/null
@@ -1,398 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to you under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.calcite.avatica.remote;
-
-import org.apache.calcite.avatica.AvaticaConnection;
-import org.apache.calcite.avatica.AvaticaStatement;
-import org.apache.calcite.avatica.ConnectionConfig;
-import org.apache.calcite.avatica.ConnectionPropertiesImpl;
-import org.apache.calcite.avatica.ConnectionSpec;
-import org.apache.calcite.avatica.Meta;
-import org.apache.calcite.avatica.jdbc.JdbcMeta;
-import org.apache.calcite.avatica.server.AvaticaJsonHandler;
-import org.apache.calcite.avatica.server.HttpServer;
-import org.apache.calcite.avatica.server.Main;
-import org.apache.calcite.avatica.server.Main.HandlerFactory;
-
-import com.google.common.cache.Cache;
-
-import org.eclipse.jetty.server.handler.AbstractHandler;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-
-/**
- * Tests that verify that the Driver still functions when requests are randomly bounced between
- * more than one server.
- */
-public class AlternatingRemoteMetaTest {
- private static final ConnectionSpec CONNECTION_SPEC = ConnectionSpec.HSQLDB;
-
- private static String url;
-
- static {
- try {
- // Force DriverManager initialization before we hit AlternatingDriver->Driver.<clinit>
- // Otherwise Driver.<clinit> -> DriverManager.registerDriver -> scan service provider files
- // causes a deadlock; see [CALCITE-1060]
- DriverManager.getDrivers();
- DriverManager.registerDriver(new AlternatingDriver());
- } catch (SQLException e) {
- throw new RuntimeException(e);
- }
- }
-
- // Keep a reference to the servers we start to clean them up after
- private static final List<HttpServer> ACTIVE_SERVERS = new ArrayList<>();
-
- /** Factory that provides a {@link JdbcMeta}. */
- public static class FullyRemoteJdbcMetaFactory implements Meta.Factory {
-
- private static JdbcMeta instance = null;
-
- private static JdbcMeta getInstance() {
- if (instance == null) {
- try {
- instance = new JdbcMeta(CONNECTION_SPEC.url, CONNECTION_SPEC.username,
- CONNECTION_SPEC.password);
- } catch (SQLException e) {
- throw new RuntimeException(e);
- }
- }
- return instance;
- }
-
- @Override public Meta create(List<String> args) {
- return getInstance();
- }
- }
-
- /**
- * AvaticaHttpClient implementation that randomly chooses among the provided URLs.
- */
- public static class AlternatingAvaticaHttpClient implements AvaticaHttpClient {
- private final List<AvaticaHttpClientImpl> clients;
- private final Random r = new Random();
-
- public AlternatingAvaticaHttpClient(List<URL> urls) {
- //System.out.println("Constructing clients for " + urls);
- clients = new ArrayList<>(urls.size());
- for (URL url : urls) {
- clients.add(new AvaticaHttpClientImpl(url));
- }
- }
-
- public byte[] send(byte[] request) {
- AvaticaHttpClientImpl client = clients.get(r.nextInt(clients.size()));
- //System.out.println("URL: " + client.url);
- return client.send(request);
- }
-
- }
-
- /**
- * Driver implementation {@link AlternatingAvaticaHttpClient}.
- */
- public static class AlternatingDriver extends Driver {
-
- public static final String PREFIX = "jdbc:avatica:remote-alternating:";
-
- @Override protected String getConnectStringPrefix() {
- return PREFIX;
- }
-
- @Override public Meta createMeta(AvaticaConnection connection) {
- final ConnectionConfig config = connection.config();
- final Service service = new RemoteService(getHttpClient(connection, config));
- connection.setService(service);
- return new RemoteMeta(connection, service);
- }
-
- @Override AvaticaHttpClient getHttpClient(AvaticaConnection connection,
- ConnectionConfig config) {
- return new AlternatingAvaticaHttpClient(parseUrls(config.url()));
- }
-
- List<URL> parseUrls(String urlStr) {
- final List<URL> urls = new ArrayList<>();
- final char comma = ',';
-
- int prevIndex = 0;
- int index = urlStr.indexOf(comma);
- if (-1 == index) {
- try {
- return Collections.singletonList(new URL(urlStr));
- } catch (MalformedURLException e) {
- throw new RuntimeException(e);
- }
- }
-
- // String split w/o regex
- while (-1 != index) {
- try {
- urls.add(new URL(urlStr.substring(prevIndex, index)));
- } catch (MalformedURLException e) {
- throw new RuntimeException(e);
- }
- prevIndex = index + 1;
- index = urlStr.indexOf(comma, prevIndex);
- }
-
- // Get the last one
- try {
- urls.add(new URL(urlStr.substring(prevIndex)));
- } catch (MalformedURLException e) {
- throw new RuntimeException(e);
- }
-
- return urls;
- }
-
- }
-
- @BeforeClass
- public static void beforeClass() throws Exception {
- final String[] mainArgs = new String[] { FullyRemoteJdbcMetaFactory.class.getName() };
-
- // Bind to '0' to pluck an ephemeral port instead of expecting a certain one to be free
-
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < 2; i++) {
- if (sb.length() > 0) {
- sb.append(",");
- }
- HttpServer jsonServer = Main.start(mainArgs, 0, new HandlerFactory() {
- @Override public AbstractHandler createHandler(Service service) {
- return new AvaticaJsonHandler(service);
- }
- });
- ACTIVE_SERVERS.add(jsonServer);
- sb.append("http://localhost:").append(jsonServer.getPort());
- }
-
- url = AlternatingDriver.PREFIX + "url=" + sb.toString();
- }
-
- @AfterClass public static void afterClass() throws Exception {
- for (HttpServer server : ACTIVE_SERVERS) {
- if (server != null) {
- server.stop();
- }
- }
- }
-
- private static Meta getMeta(AvaticaConnection conn) throws Exception {
- Field f = AvaticaConnection.class.getDeclaredField("meta");
- f.setAccessible(true);
- return (Meta) f.get(conn);
- }
-
- private static Meta.ExecuteResult prepareAndExecuteInternal(AvaticaConnection conn,
- final AvaticaStatement statement, String sql, int maxRowCount) throws Exception {
- Method m =
- AvaticaConnection.class.getDeclaredMethod("prepareAndExecuteInternal",
- AvaticaStatement.class, String.class, long.class);
- m.setAccessible(true);
- return (Meta.ExecuteResult) m.invoke(conn, statement, sql, maxRowCount);
- }
-
- private static Connection getConnection(JdbcMeta m, String id) throws Exception {
- Field f = JdbcMeta.class.getDeclaredField("connectionCache");
- f.setAccessible(true);
- //noinspection unchecked
- Cache<String, Connection> connectionCache = (Cache<String, Connection>) f.get(m);
- return connectionCache.getIfPresent(id);
- }
-
- @Test public void testRemoteExecuteMaxRowCount() throws Exception {
- ConnectionSpec.getDatabaseLock().lock();
- try (AvaticaConnection conn = (AvaticaConnection) DriverManager.getConnection(url)) {
- final AvaticaStatement statement = conn.createStatement();
- prepareAndExecuteInternal(conn, statement,
- "select * from (values ('a', 1), ('b', 2))", 0);
- ResultSet rs = statement.getResultSet();
- int count = 0;
- while (rs.next()) {
- count++;
- }
- assertEquals("Check maxRowCount=0 and ResultSets is 0 row", count, 0);
- assertEquals("Check result set meta is still there",
- rs.getMetaData().getColumnCount(), 2);
- rs.close();
- statement.close();
- conn.close();
- } finally {
- ConnectionSpec.getDatabaseLock().unlock();
- }
- }
-
- /** Test case for
- * <a href="https://issues.apache.org/jira/browse/CALCITE-780">[CALCITE-780]
- * HTTP error 413 when sending a long string to the Avatica server</a>. */
- @Test public void testRemoteExecuteVeryLargeQuery() throws Exception {
- ConnectionSpec.getDatabaseLock().lock();
- try {
- // Before the bug was fixed, a value over 7998 caused an HTTP 413.
- // 16K bytes, I guess.
- checkLargeQuery(8);
- checkLargeQuery(240);
- checkLargeQuery(8000);
- checkLargeQuery(240000);
- } finally {
- ConnectionSpec.getDatabaseLock().unlock();
- }
- }
-
- private void checkLargeQuery(int n) throws Exception {
- try (AvaticaConnection conn = (AvaticaConnection) DriverManager.getConnection(url)) {
- final AvaticaStatement statement = conn.createStatement();
- final String frenchDisko = "It said human existence is pointless\n"
- + "As acts of rebellious solidarity\n"
- + "Can bring sense in this world\n"
- + "La resistance!\n";
- final String sql = "select '"
- + longString(frenchDisko, n)
- + "' as s from (values 'x')";
- prepareAndExecuteInternal(conn, statement, sql, -1);
- ResultSet rs = statement.getResultSet();
- int count = 0;
- while (rs.next()) {
- count++;
- }
- assertThat(count, is(1));
- rs.close();
- statement.close();
- conn.close();
- }
- }
-
- /** Creates a string of exactly {@code length} characters by concatenating
- * {@code fragment}. */
- private static String longString(String fragment, int length) {
- assert fragment.length() > 0;
- final StringBuilder buf = new StringBuilder();
- while (buf.length() < length) {
- buf.append(fragment);
- }
- buf.setLength(length);
- return buf.toString();
- }
-
- @Test public void testRemoteConnectionProperties() throws Exception {
- ConnectionSpec.getDatabaseLock().lock();
- try (AvaticaConnection conn = (AvaticaConnection) DriverManager.getConnection(url)) {
- String id = conn.id;
- final Map<String, ConnectionPropertiesImpl> m = ((RemoteMeta) getMeta(conn)).propsMap;
- assertFalse("remote connection map should start ignorant", m.containsKey(id));
- // force creating a connection object on the remote side.
- try (final Statement stmt = conn.createStatement()) {
- assertTrue("creating a statement starts a local object.", m.containsKey(id));
- assertTrue(stmt.execute("select count(1) from EMP"));
- }
- Connection remoteConn = getConnection(FullyRemoteJdbcMetaFactory.getInstance(), id);
- final boolean defaultRO = remoteConn.isReadOnly();
- final boolean defaultAutoCommit = remoteConn.getAutoCommit();
- final String defaultCatalog = remoteConn.getCatalog();
- final String defaultSchema = remoteConn.getSchema();
- conn.setReadOnly(!defaultRO);
- assertTrue("local changes dirty local state", m.get(id).isDirty());
- assertEquals("remote connection has not been touched", defaultRO, remoteConn.isReadOnly());
- conn.setAutoCommit(!defaultAutoCommit);
- assertEquals("remote connection has not been touched",
- defaultAutoCommit, remoteConn.getAutoCommit());
-
- // further interaction with the connection will force a sync
- try (final Statement stmt = conn.createStatement()) {
- assertEquals(!defaultAutoCommit, remoteConn.getAutoCommit());
- assertFalse("local values should be clean", m.get(id).isDirty());
- }
- } finally {
- ConnectionSpec.getDatabaseLock().unlock();
- }
- }
-
- @Test public void testQuery() throws Exception {
- ConnectionSpec.getDatabaseLock().lock();
- try (AvaticaConnection conn = (AvaticaConnection) DriverManager.getConnection(url);
- Statement statement = conn.createStatement()) {
- assertFalse(statement.execute("SET SCHEMA \"SCOTT\""));
- assertFalse(
- statement.execute(
- "CREATE TABLE \"FOO\"(\"KEY\" INTEGER NOT NULL, \"VALUE\" VARCHAR(10))"));
- assertFalse(statement.execute("SET TABLE \"FOO\" READONLY FALSE"));
-
- final int numRecords = 1000;
- for (int i = 0; i < numRecords; i++) {
- assertFalse(statement.execute("INSERT INTO \"FOO\" VALUES(" + i + ", '" + i + "')"));
- }
-
- // Make sure all the records are there that we expect
- ResultSet results = statement.executeQuery("SELECT count(KEY) FROM FOO");
- assertTrue(results.next());
- assertEquals(1000, results.getInt(1));
- assertFalse(results.next());
-
- results = statement.executeQuery("SELECT KEY, VALUE FROM FOO ORDER BY KEY ASC");
- for (int i = 0; i < numRecords; i++) {
- assertTrue(results.next());
- assertEquals(i, results.getInt(1));
- assertEquals(Integer.toString(i), results.getString(2));
- }
- } finally {
- ConnectionSpec.getDatabaseLock().unlock();
- }
- }
-
- @Test public void testSingleUrlParsing() throws Exception {
- AlternatingDriver d = new AlternatingDriver();
- List<URL> urls = d.parseUrls("http://localhost:1234");
- assertEquals(Arrays.asList(new URL("http://localhost:1234")), urls);
- }
-
- @Test public void testMultipleUrlParsing() throws Exception {
- AlternatingDriver d = new AlternatingDriver();
- List<URL> urls = d.parseUrls("http://localhost:1234,http://localhost:2345,"
- + "http://localhost:3456");
- List<URL> expectedUrls = Arrays.asList(new URL("http://localhost:1234"),
- new URL("http://localhost:2345"), new URL("http://localhost:3456"));
- assertEquals(expectedUrls, urls);
- }
-}
-
-// End AlternatingRemoteMetaTest.java
http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/fc7b26c8/avatica/server/src/test/java/org/apache/calcite/avatica/remote/RemoteMetaTest.java
----------------------------------------------------------------------
diff --git a/avatica/server/src/test/java/org/apache/calcite/avatica/remote/RemoteMetaTest.java b/avatica/server/src/test/java/org/apache/calcite/avatica/remote/RemoteMetaTest.java
deleted file mode 100644
index ebd3c76..0000000
--- a/avatica/server/src/test/java/org/apache/calcite/avatica/remote/RemoteMetaTest.java
+++ /dev/null
@@ -1,774 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to you under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.calcite.avatica.remote;
-
-import org.apache.calcite.avatica.AvaticaConnection;
-import org.apache.calcite.avatica.AvaticaSpecificDatabaseMetaData;
-import org.apache.calcite.avatica.AvaticaSqlException;
-import org.apache.calcite.avatica.AvaticaStatement;
-import org.apache.calcite.avatica.AvaticaUtils;
-import org.apache.calcite.avatica.ConnectionPropertiesImpl;
-import org.apache.calcite.avatica.ConnectionSpec;
-import org.apache.calcite.avatica.Meta;
-import org.apache.calcite.avatica.Meta.DatabaseProperty;
-import org.apache.calcite.avatica.jdbc.JdbcMeta;
-import org.apache.calcite.avatica.remote.Service.ErrorResponse;
-import org.apache.calcite.avatica.remote.Service.Response;
-import org.apache.calcite.avatica.server.AvaticaJsonHandler;
-import org.apache.calcite.avatica.server.AvaticaProtobufHandler;
-import org.apache.calcite.avatica.server.HttpServer;
-import org.apache.calcite.avatica.server.Main;
-import org.apache.calcite.avatica.server.Main.HandlerFactory;
-import org.apache.calcite.avatica.util.ArrayImpl;
-import org.apache.calcite.avatica.util.FilteredConstants;
-
-import com.google.common.base.Throwables;
-import com.google.common.cache.Cache;
-
-import org.junit.AfterClass;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-import java.io.DataOutputStream;
-import java.io.InputStream;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.net.HttpURLConnection;
-import java.net.InetAddress;
-import java.net.URL;
-import java.nio.charset.StandardCharsets;
-import java.sql.Array;
-import java.sql.Connection;
-import java.sql.DatabaseMetaData;
-import java.sql.DriverManager;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Random;
-import java.util.UUID;
-
-import static org.hamcrest.CoreMatchers.instanceOf;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.core.StringContains.containsString;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-/** Tests covering {@link RemoteMeta}. */
-@RunWith(Parameterized.class)
-public class RemoteMetaTest {
- private static final Random RANDOM = new Random();
- private static final ConnectionSpec CONNECTION_SPEC = ConnectionSpec.HSQLDB;
-
- // Keep a reference to the servers we start to clean them up after
- private static final List<HttpServer> ACTIVE_SERVERS = new ArrayList<>();
-
- private final HttpServer server;
- private final String url;
- private final int port;
- private final Driver.Serialization serialization;
-
- @Parameters
- public static List<Object[]> parameters() throws Exception {
- List<Object[]> params = new ArrayList<>();
-
- final String[] mainArgs = { FullyRemoteJdbcMetaFactory.class.getName() };
-
- // Bind to '0' to pluck an ephemeral port instead of expecting a certain one to be free
-
- final HttpServer jsonServer = Main.start(mainArgs, 0, new HandlerFactory() {
- @Override public AvaticaJsonHandler createHandler(Service service) {
- return new AvaticaJsonHandler(service);
- }
- });
- params.add(new Object[] {jsonServer, Driver.Serialization.JSON});
- ACTIVE_SERVERS.add(jsonServer);
-
- final HttpServer protobufServer = Main.start(mainArgs, 0, new HandlerFactory() {
- @Override public AvaticaProtobufHandler createHandler(Service service) {
- return new AvaticaProtobufHandler(service);
- }
- });
- params.add(new Object[] {protobufServer, Driver.Serialization.PROTOBUF});
-
- ACTIVE_SERVERS.add(protobufServer);
-
- return params;
- }
-
- public RemoteMetaTest(HttpServer server, Driver.Serialization serialization) {
- this.server = server;
- this.port = this.server.getPort();
- this.serialization = serialization;
- url = "jdbc:avatica:remote:url=http://localhost:" + port + ";serialization="
- + serialization.name();
- }
-
- @AfterClass public static void afterClass() throws Exception {
- for (HttpServer server : ACTIVE_SERVERS) {
- if (server != null) {
- server.stop();
- }
- }
- }
-
- private static Meta getMeta(AvaticaConnection conn) throws Exception {
- Field f = AvaticaConnection.class.getDeclaredField("meta");
- f.setAccessible(true);
- return (Meta) f.get(conn);
- }
-
- private static Meta.ExecuteResult prepareAndExecuteInternal(AvaticaConnection conn,
- final AvaticaStatement statement, String sql, int maxRowCount) throws Exception {
- Method m =
- AvaticaConnection.class.getDeclaredMethod("prepareAndExecuteInternal",
- AvaticaStatement.class, String.class, long.class);
- m.setAccessible(true);
- return (Meta.ExecuteResult) m.invoke(conn, statement, sql, maxRowCount);
- }
-
- private static Connection getConnection(JdbcMeta m, String id) throws Exception {
- Field f = JdbcMeta.class.getDeclaredField("connectionCache");
- f.setAccessible(true);
- //noinspection unchecked
- Cache<String, Connection> connectionCache = (Cache<String, Connection>) f.get(m);
- return connectionCache.getIfPresent(id);
- }
-
- @Test public void testRemoteExecuteMaxRowCount() throws Exception {
- ConnectionSpec.getDatabaseLock().lock();
- try (AvaticaConnection conn = (AvaticaConnection) DriverManager.getConnection(url)) {
- final AvaticaStatement statement = conn.createStatement();
- prepareAndExecuteInternal(conn, statement,
- "select * from (values ('a', 1), ('b', 2))", 0);
- ResultSet rs = statement.getResultSet();
- int count = 0;
- while (rs.next()) {
- count++;
- }
- assertEquals("Check maxRowCount=0 and ResultSets is 0 row", count, 0);
- assertEquals("Check result set meta is still there",
- rs.getMetaData().getColumnCount(), 2);
- rs.close();
- statement.close();
- conn.close();
- } finally {
- ConnectionSpec.getDatabaseLock().unlock();
- }
- }
-
- /** Test case for
- * <a href="https://issues.apache.org/jira/browse/CALCITE-1301">[CALCITE-1301]
- * Add cancel flag to AvaticaStatement</a>. */
- @Test public void testCancel() throws Exception {
- ConnectionSpec.getDatabaseLock().lock();
- try (AvaticaConnection conn = (AvaticaConnection) DriverManager.getConnection(url)) {
- final AvaticaStatement statement = conn.createStatement();
- final String sql = "select * from (values ('a', 1), ('b', 2))";
- final ResultSet rs = statement.executeQuery(sql);
- int count = 0;
- loop:
- for (;;) {
- switch (count++) {
- case 0:
- assertThat(rs.next(), is(true));
- break;
- case 1:
- rs.getStatement().cancel();
- try {
- boolean x = rs.next();
- fail("expected exception, got " + x);
- } catch (SQLException e) {
- assertThat(e.getMessage(), is("Statement canceled"));
- }
- break loop;
- default:
- fail("count: " + count);
- }
- }
- assertThat(count, is(2));
- assertThat(statement.isClosed(), is(false));
- rs.close();
- assertThat(statement.isClosed(), is(false));
- statement.close();
- assertThat(statement.isClosed(), is(true));
- statement.close();
- assertThat(statement.isClosed(), is(true));
- } finally {
- ConnectionSpec.getDatabaseLock().unlock();
- }
- }
-
- /** Test case for
- * <a href="https://issues.apache.org/jira/browse/CALCITE-780">[CALCITE-780]
- * HTTP error 413 when sending a long string to the Avatica server</a>. */
- @Test public void testRemoteExecuteVeryLargeQuery() throws Exception {
- ConnectionSpec.getDatabaseLock().lock();
- try {
- // Before the bug was fixed, a value over 7998 caused an HTTP 413.
- // 16K bytes, I guess.
- checkLargeQuery(8);
- checkLargeQuery(240);
- checkLargeQuery(8000);
- checkLargeQuery(240000);
- } finally {
- ConnectionSpec.getDatabaseLock().unlock();
- }
- }
-
- private void checkLargeQuery(int n) throws Exception {
- try (AvaticaConnection conn = (AvaticaConnection) DriverManager.getConnection(url)) {
- final AvaticaStatement statement = conn.createStatement();
- final String frenchDisko = "It said human existence is pointless\n"
- + "As acts of rebellious solidarity\n"
- + "Can bring sense in this world\n"
- + "La resistance!\n";
- final String sql = "select '"
- + longString(frenchDisko, n)
- + "' as s from (values 'x')";
- prepareAndExecuteInternal(conn, statement, sql, -1);
- ResultSet rs = statement.getResultSet();
- int count = 0;
- while (rs.next()) {
- count++;
- }
- assertThat(count, is(1));
- rs.close();
- statement.close();
- conn.close();
- }
- }
-
- /** Creates a string of exactly {@code length} characters by concatenating
- * {@code fragment}. */
- private static String longString(String fragment, int length) {
- assert fragment.length() > 0;
- final StringBuilder buf = new StringBuilder();
- while (buf.length() < length) {
- buf.append(fragment);
- }
- buf.setLength(length);
- return buf.toString();
- }
-
- @Test public void testRemoteConnectionProperties() throws Exception {
- ConnectionSpec.getDatabaseLock().lock();
- try (AvaticaConnection conn = (AvaticaConnection) DriverManager.getConnection(url)) {
- String id = conn.id;
- final Map<String, ConnectionPropertiesImpl> m = ((RemoteMeta) getMeta(conn)).propsMap;
- assertFalse("remote connection map should start ignorant", m.containsKey(id));
- // force creating a connection object on the remote side.
- try (final Statement stmt = conn.createStatement()) {
- assertTrue("creating a statement starts a local object.", m.containsKey(id));
- assertTrue(stmt.execute("select count(1) from EMP"));
- }
- Connection remoteConn = getConnection(FullyRemoteJdbcMetaFactory.getInstance(), id);
- final boolean defaultRO = remoteConn.isReadOnly();
- final boolean defaultAutoCommit = remoteConn.getAutoCommit();
- final String defaultCatalog = remoteConn.getCatalog();
- final String defaultSchema = remoteConn.getSchema();
- conn.setReadOnly(!defaultRO);
- assertTrue("local changes dirty local state", m.get(id).isDirty());
- assertEquals("remote connection has not been touched", defaultRO, remoteConn.isReadOnly());
- conn.setAutoCommit(!defaultAutoCommit);
- assertEquals("remote connection has not been touched",
- defaultAutoCommit, remoteConn.getAutoCommit());
-
- // further interaction with the connection will force a sync
- try (final Statement stmt = conn.createStatement()) {
- assertEquals(!defaultAutoCommit, remoteConn.getAutoCommit());
- assertFalse("local values should be clean", m.get(id).isDirty());
- }
- } finally {
- ConnectionSpec.getDatabaseLock().unlock();
- }
- }
-
- @Test public void testRemoteStatementInsert() throws Exception {
- ConnectionSpec.getDatabaseLock().lock();
- try {
- final String t = AvaticaUtils.unique("TEST_TABLE2");
- AvaticaConnection conn = (AvaticaConnection) DriverManager.getConnection(url);
- Statement statement = conn.createStatement();
- final String create =
- String.format(Locale.ROOT, "create table if not exists %s ("
- + " id int not null, msg varchar(255) not null)", t);
- int status = statement.executeUpdate(create);
- assertEquals(status, 0);
-
- statement = conn.createStatement();
- final String update =
- String.format(Locale.ROOT, "insert into %s values ('%d', '%s')",
- t, RANDOM.nextInt(Integer.MAX_VALUE), UUID.randomUUID());
- status = statement.executeUpdate(update);
- assertEquals(status, 1);
- } finally {
- ConnectionSpec.getDatabaseLock().unlock();
- }
- }
-
- @Test public void testBigints() throws Exception {
- final String table = "TESTBIGINTS";
- ConnectionSpec.getDatabaseLock().lock();
- try (AvaticaConnection conn = (AvaticaConnection) DriverManager.getConnection(url);
- Statement stmt = conn.createStatement()) {
- assertFalse(stmt.execute("DROP TABLE IF EXISTS " + table));
- assertFalse(stmt.execute("CREATE TABLE " + table + " (id BIGINT)"));
- assertFalse(stmt.execute("INSERT INTO " + table + " values(10)"));
- ResultSet results = conn.getMetaData().getColumns(null, null, table, null);
- assertTrue(results.next());
- assertEquals(table, results.getString(3));
- // ordinal position
- assertEquals(1L, results.getLong(17));
- } finally {
- ConnectionSpec.getDatabaseLock().unlock();
- }
- }
-
- @Test public void testOpenConnectionWithProperties() throws Exception {
- // This tests that username and password are used for creating a connection on the
- // server. If this was not the case, it would succeed.
- try {
- DriverManager.getConnection(url, "john", "doe");
- fail("expected exception");
- } catch (RuntimeException e) {
- assertEquals("Remote driver error: RuntimeException: "
- + "java.sql.SQLInvalidAuthorizationSpecException: invalid authorization specification"
- + " - not found: john"
- + " -> SQLInvalidAuthorizationSpecException: invalid authorization specification - "
- + "not found: john"
- + " -> HsqlException: invalid authorization specification - not found: john",
- e.getMessage());
- }
- }
-
- @Test public void testRemoteConnectionsAreDifferent() throws SQLException {
- ConnectionSpec.getDatabaseLock().lock();
- try {
- Connection conn1 = DriverManager.getConnection(url);
- Statement stmt = conn1.createStatement();
- stmt.execute("DECLARE LOCAL TEMPORARY TABLE"
- + " buffer (id INTEGER PRIMARY KEY, textdata VARCHAR(100))");
- stmt.execute("insert into buffer(id, textdata) values(1, 'abc')");
- stmt.executeQuery("select * from buffer");
-
- // The local temporary table is local to the connection above, and should
- // not be visible on another connection
- Connection conn2 = DriverManager.getConnection(url);
- Statement stmt2 = conn2.createStatement();
- try {
- stmt2.executeQuery("select * from buffer");
- fail("expected exception");
- } catch (Exception e) {
- assertEquals("Error -1 (00000) : Error while executing SQL \"select * from buffer\": "
- + "Remote driver error: RuntimeException: java.sql.SQLSyntaxErrorException: "
- + "user lacks privilege or object not found: BUFFER -> "
- + "SQLSyntaxErrorException: user lacks privilege or object not found: BUFFER -> "
- + "HsqlException: user lacks privilege or object not found: BUFFER",
- e.getMessage());
- }
- } finally {
- ConnectionSpec.getDatabaseLock().unlock();
- }
- }
-
- @Ignore("[CALCITE-942] AvaticaConnection should fail-fast when closed.")
- @Test public void testRemoteConnectionClosing() throws Exception {
- AvaticaConnection conn = (AvaticaConnection) DriverManager.getConnection(url);
- // Verify connection is usable
- conn.createStatement();
- conn.close();
-
- // After closing the connection, it should not be usable anymore
- try {
- conn.createStatement();
- fail("expected exception");
- } catch (SQLException e) {
- assertThat(e.getMessage(),
- containsString("Connection is closed"));
- }
- }
-
- @Test public void testExceptionPropagation() throws Exception {
- final String sql = "SELECT * from EMP LIMIT FOOBARBAZ";
- ConnectionSpec.getDatabaseLock().lock();
- try (final AvaticaConnection conn = (AvaticaConnection) DriverManager.getConnection(url);
- final Statement stmt = conn.createStatement()) {
- try {
- // invalid SQL
- stmt.execute(sql);
- fail("Expected an AvaticaSqlException");
- } catch (AvaticaSqlException e) {
- assertEquals(ErrorResponse.UNKNOWN_ERROR_CODE, e.getErrorCode());
- assertEquals(ErrorResponse.UNKNOWN_SQL_STATE, e.getSQLState());
- assertTrue("Message should contain original SQL, was '" + e.getMessage() + "'",
- e.getMessage().contains(sql));
- assertEquals(1, e.getStackTraces().size());
- final String stacktrace = e.getStackTraces().get(0);
- final String substring = "unexpected token: FOOBARBAZ";
- assertTrue("Message should contain '" + substring + "', was '" + e.getMessage() + ",",
- stacktrace.contains(substring));
- }
- } finally {
- ConnectionSpec.getDatabaseLock().unlock();
- }
- }
-
- @Test public void testRemoteColumnsMeta() throws Exception {
- ConnectionSpec.getDatabaseLock().lock();
- try {
- // Verify all columns are retrieved, thus that frame-based fetching works correctly
- // for columns
- int rowCount = 0;
- try (AvaticaConnection conn = (AvaticaConnection) DriverManager.getConnection(url)) {
- ResultSet rs = conn.getMetaData().getColumns(null, null, null, null);
- while (rs.next()) {
- rowCount++;
- }
- rs.close();
-
- // The implicitly created statement should have been closed
- assertTrue(rs.getStatement().isClosed());
- }
- // default fetch size is 100, we are well beyond it
- assertTrue(rowCount > 900);
- } finally {
- ConnectionSpec.getDatabaseLock().unlock();
- }
- }
-
- @Test public void testArrays() throws SQLException {
- ConnectionSpec.getDatabaseLock().lock();
- try (AvaticaConnection conn = (AvaticaConnection) DriverManager.getConnection(url);
- Statement stmt = conn.createStatement()) {
- ResultSet resultSet =
- stmt.executeQuery("select * from (values ('a', array['b', 'c']));");
-
- assertTrue(resultSet.next());
- assertEquals("a", resultSet.getString(1));
- Array arr = resultSet.getArray(2);
- assertTrue(arr instanceof ArrayImpl);
- Object[] values = (Object[]) ((ArrayImpl) arr).getArray();
- assertArrayEquals(new String[]{"b", "c"}, values);
- } finally {
- ConnectionSpec.getDatabaseLock().unlock();
- }
- }
-
- @Test public void testBinaryAndStrings() throws Exception {
- final String tableName = "testbinaryandstrs";
- final byte[] data = "asdf".getBytes(StandardCharsets.UTF_8);
- ConnectionSpec.getDatabaseLock().lock();
- try (final Connection conn = DriverManager.getConnection(url);
- final Statement stmt = conn.createStatement()) {
- assertFalse(stmt.execute("DROP TABLE IF EXISTS " + tableName));
- assertFalse(stmt.execute("CREATE TABLE " + tableName + "(id int, bin BINARY(4))"));
- try (final PreparedStatement prepStmt = conn.prepareStatement(
- "INSERT INTO " + tableName + " values(1, ?)")) {
- prepStmt.setBytes(1, data);
- assertFalse(prepStmt.execute());
- }
- try (ResultSet results = stmt.executeQuery("SELECT id, bin from " + tableName)) {
- assertTrue(results.next());
- assertEquals(1, results.getInt(1));
- // byte comparison should work
- assertArrayEquals("Bytes were " + Arrays.toString(results.getBytes(2)),
- data, results.getBytes(2));
- // as should string
- assertEquals(new String(data, StandardCharsets.UTF_8), results.getString(2));
- assertFalse(results.next());
- }
- } finally {
- ConnectionSpec.getDatabaseLock().unlock();
- }
- }
-
- @Test public void testLocalStackTraceHasServerStackTrace() {
- ConnectionSpec.getDatabaseLock().lock();
- try {
- Statement statement = DriverManager.getConnection(url).createStatement();
- statement.executeQuery("SELECT * FROM BOGUS_TABLE_DEF_DOESNT_EXIST");
- } catch (SQLException e) {
- // Verify that we got the expected exception
- assertThat(e, instanceOf(AvaticaSqlException.class));
-
- // Attempt to verify that we got a "server-side" class in the stack.
- assertThat(Throwables.getStackTraceAsString(e),
- containsString(JdbcMeta.class.getName()));
- } finally {
- ConnectionSpec.getDatabaseLock().unlock();
- }
- }
-
- @Test public void testServerAddressInResponse() throws Exception {
- ConnectionSpec.getDatabaseLock().lock();
- try {
- URL url = new URL("http://localhost:" + this.port);
- AvaticaHttpClient httpClient = new AvaticaHttpClientImpl(url);
- byte[] request;
-
- Service.OpenConnectionRequest jsonReq = new Service.OpenConnectionRequest(
- UUID.randomUUID().toString(), Collections.<String, String>emptyMap());
- switch (this.serialization) {
- case JSON:
- request = JsonService.MAPPER.writeValueAsBytes(jsonReq);
- break;
- case PROTOBUF:
- ProtobufTranslation pbTranslation = new ProtobufTranslationImpl();
- request = pbTranslation.serializeRequest(jsonReq);
- break;
- default:
- throw new IllegalStateException("Should not reach here");
- }
-
- byte[] response = httpClient.send(request);
- Service.OpenConnectionResponse openCnxnResp;
- switch (this.serialization) {
- case JSON:
- openCnxnResp = JsonService.MAPPER.readValue(response,
- Service.OpenConnectionResponse.class);
- break;
- case PROTOBUF:
- ProtobufTranslation pbTranslation = new ProtobufTranslationImpl();
- Response genericResp = pbTranslation.parseResponse(response);
- assertTrue("Expected an OpenConnnectionResponse, but got " + genericResp.getClass(),
- genericResp instanceof Service.OpenConnectionResponse);
- openCnxnResp = (Service.OpenConnectionResponse) genericResp;
- break;
- default:
- throw new IllegalStateException("Should not reach here");
- }
-
- String hostname = InetAddress.getLocalHost().getHostName();
-
- assertNotNull(openCnxnResp.rpcMetadata);
- assertEquals(hostname + ":" + this.port, openCnxnResp.rpcMetadata.serverAddress);
- } finally {
- ConnectionSpec.getDatabaseLock().unlock();
- }
- }
-
- @Test public void testCommitRollback() throws Exception {
- final String productTable = "commitrollback_products";
- final String salesTable = "commitrollback_sales";
- ConnectionSpec.getDatabaseLock().lock();
- try (final Connection conn = DriverManager.getConnection(url);
- final Statement stmt = conn.createStatement()) {
- assertFalse(stmt.execute("DROP TABLE IF EXISTS " + productTable));
- assertFalse(
- stmt.execute(
- String.format(Locale.ROOT,
- "CREATE TABLE %s(id integer, stock integer)",
- productTable)));
- assertFalse(stmt.execute("DROP TABLE IF EXISTS " + salesTable));
- assertFalse(
- stmt.execute(
- String.format(Locale.ROOT,
- "CREATE TABLE %s(id integer, units_sold integer)",
- salesTable)));
-
- final int productId = 1;
- // No products and no sales
- assertFalse(
- stmt.execute(
- String.format(Locale.ROOT, "INSERT INTO %s VALUES(%d, 0)",
- productTable, productId)));
- assertFalse(
- stmt.execute(
- String.format(Locale.ROOT, "INSERT INTO %s VALUES(%d, 0)",
- salesTable, productId)));
-
- conn.setAutoCommit(false);
- PreparedStatement productStmt = conn.prepareStatement(
- String.format(Locale.ROOT,
- "UPDATE %s SET stock = stock + ? WHERE id = ?", productTable));
- PreparedStatement salesStmt = conn.prepareStatement(
- String.format(Locale.ROOT,
- "UPDATE %s SET units_sold = units_sold + ? WHERE id = ?",
- salesTable));
-
- // No stock
- assertEquals(0, getInventory(conn, productTable, productId));
-
- // Set a stock of 10 for product 1
- productStmt.setInt(1, 10);
- productStmt.setInt(2, productId);
- productStmt.executeUpdate();
-
- conn.commit();
- assertEquals(10, getInventory(conn, productTable, productId));
-
- // Sold 5 items (5 in stock, 5 sold)
- productStmt.setInt(1, -5);
- productStmt.setInt(2, productId);
- productStmt.executeUpdate();
- salesStmt.setInt(1, 5);
- salesStmt.setInt(2, productId);
- salesStmt.executeUpdate();
-
- conn.commit();
- // We will definitely see the updated values
- assertEquals(5, getInventory(conn, productTable, productId));
- assertEquals(5, getSales(conn, salesTable, productId));
-
- // Update some "bad" values
- productStmt.setInt(1, -10);
- productStmt.setInt(2, productId);
- productStmt.executeUpdate();
- salesStmt.setInt(1, 10);
- salesStmt.setInt(2, productId);
- salesStmt.executeUpdate();
-
- // We just went negative, nonsense. Better rollback.
- conn.rollback();
-
- // Should still have 5 and 5
- assertEquals(5, getInventory(conn, productTable, productId));
- assertEquals(5, getSales(conn, salesTable, productId));
- } finally {
- ConnectionSpec.getDatabaseLock().unlock();
- }
- }
-
- private int getInventory(Connection conn, String productTable, int productId) throws Exception {
- try (Statement stmt = conn.createStatement()) {
- ResultSet results = stmt.executeQuery(
- String.format(Locale.ROOT, "SELECT stock FROM %s WHERE id = %d",
- productTable, productId));
- assertTrue(results.next());
- return results.getInt(1);
- }
- }
-
- private int getSales(Connection conn, String salesTable, int productId) throws Exception {
- try (Statement stmt = conn.createStatement()) {
- ResultSet results = stmt.executeQuery(
- String.format(Locale.ROOT, "SELECT units_sold FROM %s WHERE id = %d",
- salesTable, productId));
- assertTrue(results.next());
- return results.getInt(1);
- }
- }
-
- @Test public void getAvaticaVersion() throws Exception {
- ConnectionSpec.getDatabaseLock().lock();
- try (final Connection conn = DriverManager.getConnection(url)) {
- DatabaseMetaData metadata = conn.getMetaData();
- assertTrue("DatabaseMetaData is not an instance of AvaticaDatabaseMetaData",
- metadata instanceof AvaticaSpecificDatabaseMetaData);
- AvaticaSpecificDatabaseMetaData avaticaMetadata = (AvaticaSpecificDatabaseMetaData) metadata;
- // We should get the same version back from the server
- assertEquals(FilteredConstants.VERSION, avaticaMetadata.getAvaticaServerVersion());
-
- Properties avaticaProps = avaticaMetadata.unwrap(Properties.class);
- assertNotNull(avaticaProps);
- assertEquals(FilteredConstants.VERSION,
- avaticaProps.get(DatabaseProperty.AVATICA_VERSION.name()));
- } finally {
- ConnectionSpec.getDatabaseLock().unlock();
- }
- }
-
- @Test public void testMalformedRequest() throws Exception {
- URL url = new URL("http://localhost:" + this.port);
-
- HttpURLConnection conn = (HttpURLConnection) url.openConnection();
- conn.setRequestMethod("POST");
- conn.setDoInput(true);
- conn.setDoOutput(true);
-
- try (DataOutputStream wr = new DataOutputStream(conn.getOutputStream())) {
- // Write some garbage data
- wr.write(new byte[] {0, 1, 2, 3, 4, 5, 6, 7});
- wr.flush();
- wr.close();
- }
- final int responseCode = conn.getResponseCode();
- assertEquals(500, responseCode);
- final InputStream inputStream = conn.getErrorStream();
- byte[] responseBytes = AvaticaUtils.readFullyToBytes(inputStream);
- ErrorResponse response;
- switch (this.serialization) {
- case JSON:
- response = JsonService.MAPPER.readValue(responseBytes, ErrorResponse.class);
- assertTrue("Unexpected error message: " + response.errorMessage,
- response.errorMessage.contains("Illegal character"));
- break;
- case PROTOBUF:
- ProtobufTranslation pbTranslation = new ProtobufTranslationImpl();
- Response genericResp = pbTranslation.parseResponse(responseBytes);
- assertTrue("Response was not an ErrorResponse, but was " + genericResp.getClass(),
- genericResp instanceof ErrorResponse);
- response = (ErrorResponse) genericResp;
- assertTrue("Unexpected error message: " + response.errorMessage,
- response.errorMessage.contains("contained an invalid tag"));
- break;
- default:
- fail("Unhandled serialization " + this.serialization);
- throw new RuntimeException();
- }
- }
-
- @Test public void testDriverProperties() throws Exception {
- final Properties props = new Properties();
- props.setProperty("foo", "bar");
- final Properties originalProps = (Properties) props.clone();
- try (final Connection conn = DriverManager.getConnection(url, props)) {
- // The contents of the two properties objects should not have changed after connecting.
- assertEquals(props, originalProps);
- }
- }
-
- /** Factory that provides a {@link JdbcMeta}. */
- public static class FullyRemoteJdbcMetaFactory implements Meta.Factory {
-
- private static JdbcMeta instance = null;
-
- private static JdbcMeta getInstance() {
- if (instance == null) {
- try {
- instance = new JdbcMeta(CONNECTION_SPEC.url, CONNECTION_SPEC.username,
- CONNECTION_SPEC.password);
- } catch (SQLException e) {
- throw new RuntimeException(e);
- }
- }
- return instance;
- }
-
- @Override public Meta create(List<String> args) {
- return getInstance();
- }
- }
-}
-
-// End RemoteMetaTest.java
http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/fc7b26c8/avatica/server/src/test/java/org/apache/calcite/avatica/server/AbstractAvaticaHandlerTest.java
----------------------------------------------------------------------
diff --git a/avatica/server/src/test/java/org/apache/calcite/avatica/server/AbstractAvaticaHandlerTest.java b/avatica/server/src/test/java/org/apache/calcite/avatica/server/AbstractAvaticaHandlerTest.java
deleted file mode 100644
index 66eb361..0000000
--- a/avatica/server/src/test/java/org/apache/calcite/avatica/server/AbstractAvaticaHandlerTest.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to you under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.calcite.avatica.server;
-
-import org.apache.calcite.avatica.remote.AuthenticationType;
-
-import org.hamcrest.BaseMatcher;
-import org.hamcrest.Description;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.net.HttpURLConnection;
-import java.nio.charset.StandardCharsets;
-
-import javax.servlet.ServletOutputStream;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.mockito.hamcrest.MockitoHamcrest.argThat;
-
-/**
- * Test class for logic common to all {@link AvaticaHandler}'s.
- */
-public class AbstractAvaticaHandlerTest {
-
- private AbstractAvaticaHandler handler;
- private AvaticaServerConfiguration config;
- private HttpServletRequest request;
- private HttpServletResponse response;
-
- @Before public void setup() throws Exception {
- handler = mock(AbstractAvaticaHandler.class);
- config = mock(AvaticaServerConfiguration.class);
- request = mock(HttpServletRequest.class);
- response = mock(HttpServletResponse.class);
- when(handler.isUserPermitted(config, request, response)).thenCallRealMethod();
- }
-
- @Test public void disallowUnauthenticatedUsers() throws Exception {
- ServletOutputStream os = mock(ServletOutputStream.class);
-
- when(config.getAuthenticationType()).thenReturn(AuthenticationType.SPNEGO);
- when(request.getRemoteUser()).thenReturn(null);
- when(response.getOutputStream()).thenReturn(os);
-
- assertFalse(handler.isUserPermitted(config, request, response));
-
- verify(response).setStatus(HttpURLConnection.HTTP_UNAUTHORIZED);
- // Make sure that the serialized ErrorMessage looks reasonable
- verify(os).write(argThat(new BaseMatcher<byte[]>() {
- @Override public void describeTo(Description description) {
- String desc = "A serialized ErrorMessage which contains 'User is not authenticated'";
- description.appendText(desc);
- }
-
- @Override public boolean matches(Object item) {
- String msg = new String((byte[]) item, StandardCharsets.UTF_8);
- return msg.contains("User is not authenticated");
- }
-
- @Override public void describeMismatch(Object item, Description mismatchDescription) {
- mismatchDescription.appendText("The message should contain 'User is not authenticated'");
- }
- }));
- }
-
- @Test public void allowAuthenticatedUsers() throws Exception {
- when(config.getAuthenticationType()).thenReturn(AuthenticationType.SPNEGO);
- when(request.getRemoteUser()).thenReturn("user1");
- assertTrue(handler.isUserPermitted(config, request, response));
- }
-
- @Test public void allowAllUsersWhenNoAuthenticationIsNeeded() throws Exception {
- when(config.getAuthenticationType()).thenReturn(AuthenticationType.NONE);
- when(request.getRemoteUser()).thenReturn(null);
- assertTrue(handler.isUserPermitted(config, request, response));
-
- when(request.getRemoteUser()).thenReturn("user1");
- assertTrue(handler.isUserPermitted(config, request, response));
- }
-}
-
-// End AbstractAvaticaHandlerTest.java
http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/fc7b26c8/avatica/server/src/test/java/org/apache/calcite/avatica/server/BasicAuthHttpServerTest.java
----------------------------------------------------------------------
diff --git a/avatica/server/src/test/java/org/apache/calcite/avatica/server/BasicAuthHttpServerTest.java b/avatica/server/src/test/java/org/apache/calcite/avatica/server/BasicAuthHttpServerTest.java
deleted file mode 100644
index 6f5f872..0000000
--- a/avatica/server/src/test/java/org/apache/calcite/avatica/server/BasicAuthHttpServerTest.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to you under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.calcite.avatica.server;
-
-import org.apache.calcite.avatica.ConnectionSpec;
-import org.apache.calcite.avatica.jdbc.JdbcMeta;
-import org.apache.calcite.avatica.remote.Driver;
-import org.apache.calcite.avatica.remote.LocalService;
-
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import java.util.Properties;
-
-import static org.hamcrest.core.StringContains.containsString;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.fail;
-
-/**
- * Test class for HTTP Basic authentication.
- */
-public class BasicAuthHttpServerTest extends HttpAuthBase {
-
- private static final ConnectionSpec CONNECTION_SPEC = ConnectionSpec.HSQLDB;
- private static HttpServer server;
- private static String url;
-
- @BeforeClass public static void startServer() throws Exception {
- final String userPropertiesFile = BasicAuthHttpServerTest.class
- .getResource("/auth-users.properties").getFile();
- assertNotNull("Could not find properties file for basic auth users", userPropertiesFile);
-
- // Create a LocalService around HSQLDB
- final JdbcMeta jdbcMeta = new JdbcMeta(CONNECTION_SPEC.url,
- CONNECTION_SPEC.username, CONNECTION_SPEC.password);
- LocalService service = new LocalService(jdbcMeta);
-
- server = new HttpServer.Builder()
- .withBasicAuthentication(userPropertiesFile, new String[] { "users" })
- .withHandler(service, Driver.Serialization.PROTOBUF)
- .withPort(0)
- .build();
- server.start();
-
- url = "jdbc:avatica:remote:url=http://localhost:" + server.getPort()
- + ";authentication=BASIC;serialization=PROTOBUF";
-
- // Create and grant permissions to our users
- createHsqldbUsers();
- }
-
- @AfterClass public static void stopServer() throws Exception {
- if (null != server) {
- server.stop();
- }
- }
-
- @Test public void testDisallowedAvaticaAllowedDbUser() throws Exception {
- // Allowed by avatica and hsqldb
- final Properties props = new Properties();
- props.put("avatica_user", "USER2");
- props.put("avatica_password", "foo");
- props.put("user", "USER2");
- props.put("password", "password2");
-
- try {
- readWriteData(url, "INVALID_AVATICA_USER_VALID_DB_USER", props);
- fail("Expected an exception");
- } catch (RuntimeException e) {
- assertThat(e.getMessage(), containsString("HTTP/401"));
- }
- }
-
- @Test public void testDisallowedAvaticaNoDbUser() throws Exception {
- // Allowed by avatica and hsqldb
- final Properties props = new Properties();
- props.put("avatica_user", "USER2");
- props.put("avatica_password", "password2");
-
- readWriteData(url, "INVALID_AVATICA_USER_NO_DB_USER", props);
- }
-
- @Test public void testValidUser() throws Exception {
- // Allowed by avatica and hsqldb
- final Properties props = new Properties();
- props.put("avatica_user", "USER2");
- props.put("avatica_password", "password2");
- props.put("user", "USER2");
- props.put("password", "password2");
-
- readWriteData(url, "VALID_USER", props);
- }
-
- @Test public void testInvalidUser() throws Exception {
- // Denied by avatica
- final Properties props = new Properties();
- props.put("user", "foo");
- props.put("password", "bar");
-
- try {
- readWriteData(url, "INVALID_USER", props);
- fail("Expected an exception");
- } catch (RuntimeException e) {
- assertThat(e.getMessage(), containsString("HTTP/401"));
- }
- }
-
- @Test public void testUserWithDisallowedRole() throws Exception {
- // Disallowed by avatica
- final Properties props = new Properties();
- props.put("avatica_user", "USER4");
- props.put("avatica_password", "password4");
-
- try {
- readWriteData(url, "DISALLOWED_AVATICA_USER", props);
- fail("Expected an exception");
- } catch (RuntimeException e) {
- assertThat(e.getMessage(), containsString("HTTP/403"));
- }
- }
-
- @Test public void testDisallowedDbUser() throws Exception {
- // Disallowed by hsqldb, allowed by avatica
- final Properties props = new Properties();
- props.put("avatica_user", "USER1");
- props.put("avatica_password", "password1");
- props.put("user", "USER1");
- props.put("password", "password1");
-
- try {
- readWriteData(url, "DISALLOWED_DB_USER", props);
- fail("Expected an exception");
- } catch (RuntimeException e) {
- assertEquals("Remote driver error: RuntimeException: "
- + "java.sql.SQLInvalidAuthorizationSpecException: invalid authorization specification"
- + " - not found: USER1"
- + " -> SQLInvalidAuthorizationSpecException: invalid authorization specification - "
- + "not found: USER1"
- + " -> HsqlException: invalid authorization specification - not found: USER1",
- e.getMessage());
- }
- }
-}
-
-// End BasicAuthHttpServerTest.java