This is an automated email from the ASF dual-hosted git repository.
jshao pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git
The following commit(s) were added to refs/heads/main by this push:
new 1fd222590 [#5520] improvement(JDBC-connection): handle JDBC access
denied exception (#5546)
1fd222590 is described below
commit 1fd2225901680f8200066adb3532a8110360ebca
Author: mchades <[email protected]>
AuthorDate: Wed Nov 27 14:14:25 2024 +0800
[#5520] improvement(JDBC-connection): handle JDBC access denied exception
(#5546)
### What changes were proposed in this pull request?
catch JDBC access denied exception and convert to UnauthorizedException
### Why are the changes needed?
The REST client need the real exception instead of
GravitinoRuntimeException
Fix: #5520
### Does this PR introduce _any_ user-facing change?
no
### How was this patch tested?
ITs added
---
.../catalog/jdbc/JdbcCatalogOperations.java | 15 +++--------
.../MySQLProtocolCompatibleCatalogOperations.java | 3 +--
.../jdbc/converter/JdbcExceptionConverter.java | 5 ++++
.../doris/converter/DorisExceptionConverter.java | 4 +++
.../doris/integration/test/CatalogDorisIT.java | 25 ++++++++++++++++++-
.../mysql/integration/test/CatalogMysqlIT.java | 29 ++++++++++++++++++++++
.../integration/test/CatalogOceanBaseIT.java | 29 ++++++++++++++++++++++
.../converter/PostgreSqlExceptionConverter.java | 4 +++
.../integration/test/CatalogPostgreSqlIT.java | 27 ++++++++++++++++++++
.../integration/test/TestMultipleJDBCLoad.java | 19 +++++++++++++-
.../lakehouse/paimon/utils/CatalogUtils.java | 13 +++++++++-
.../integration/test/CatalogPaimonBaseIT.java | 4 +--
.../integration/test/CatalogPaimonJdbcIT.java | 23 +++++++++++++++++
.../gravitino/dto/responses/ErrorResponse.java | 4 +--
.../iceberg/common/utils/IcebergCatalogUtil.java | 14 ++++++++++-
15 files changed, 196 insertions(+), 22 deletions(-)
diff --git
a/catalogs/catalog-jdbc-common/src/main/java/org/apache/gravitino/catalog/jdbc/JdbcCatalogOperations.java
b/catalogs/catalog-jdbc-common/src/main/java/org/apache/gravitino/catalog/jdbc/JdbcCatalogOperations.java
index aef5ecac3..56490d475 100644
---
a/catalogs/catalog-jdbc-common/src/main/java/org/apache/gravitino/catalog/jdbc/JdbcCatalogOperations.java
+++
b/catalogs/catalog-jdbc-common/src/main/java/org/apache/gravitino/catalog/jdbc/JdbcCatalogOperations.java
@@ -56,7 +56,6 @@ import org.apache.gravitino.connector.CatalogInfo;
import org.apache.gravitino.connector.CatalogOperations;
import org.apache.gravitino.connector.HasPropertyMetadata;
import org.apache.gravitino.connector.SupportsSchemas;
-import org.apache.gravitino.exceptions.GravitinoRuntimeException;
import org.apache.gravitino.exceptions.NoSuchCatalogException;
import org.apache.gravitino.exceptions.NoSuchSchemaException;
import org.apache.gravitino.exceptions.NoSuchTableException;
@@ -521,20 +520,12 @@ public class JdbcCatalogOperations implements
CatalogOperations, SupportsSchemas
metaData.getDriverMajorVersion(),
metaData.getDriverMinorVersion());
} catch (final SQLException se) {
- throw new GravitinoRuntimeException(
- se, "Failed to get JDBC driver information %s: ", se.getMessage());
+ throw exceptionConverter.toGravitinoException(se);
}
}
- /**
- * Check the version of JDBC driver can supported.
- *
- * @return Returns the result of checking the jdbc driver version. If
success return true,
- * otherwise throw a RuntimeException
- */
- public boolean checkJDBCDriverVersion() {
- return true;
- }
+ /** Check if the JDBC driver version is supported. If not, throw an
exception. */
+ public void checkJDBCDriverVersion() {}
private Table internalAlterTable(NameIdentifier tableIdent, TableChange...
changes)
throws NoSuchTableException, IllegalArgumentException {
diff --git
a/catalogs/catalog-jdbc-common/src/main/java/org/apache/gravitino/catalog/jdbc/MySQLProtocolCompatibleCatalogOperations.java
b/catalogs/catalog-jdbc-common/src/main/java/org/apache/gravitino/catalog/jdbc/MySQLProtocolCompatibleCatalogOperations.java
index 35f3a659c..b4ee565dc 100644
---
a/catalogs/catalog-jdbc-common/src/main/java/org/apache/gravitino/catalog/jdbc/MySQLProtocolCompatibleCatalogOperations.java
+++
b/catalogs/catalog-jdbc-common/src/main/java/org/apache/gravitino/catalog/jdbc/MySQLProtocolCompatibleCatalogOperations.java
@@ -50,7 +50,7 @@ public class MySQLProtocolCompatibleCatalogOperations extends
JdbcCatalogOperati
}
@Override
- public boolean checkJDBCDriverVersion() {
+ public void checkJDBCDriverVersion() {
JDBCDriverInfo driverInfo = getDiverInfo();
if (driverInfo.majorVersion < MYSQL_JDBC_DRIVER_MINIMAL_SUPPORT_VERSION) {
throw new RuntimeException(
@@ -58,7 +58,6 @@ public class MySQLProtocolCompatibleCatalogOperations extends
JdbcCatalogOperati
"Mysql catalog does not support the jdbc driver version %s,
minimal required version is 8.0",
driverInfo.version));
}
- return true;
}
@Override
diff --git
a/catalogs/catalog-jdbc-common/src/main/java/org/apache/gravitino/catalog/jdbc/converter/JdbcExceptionConverter.java
b/catalogs/catalog-jdbc-common/src/main/java/org/apache/gravitino/catalog/jdbc/converter/JdbcExceptionConverter.java
index 716cfc28d..d4a60c8db 100644
---
a/catalogs/catalog-jdbc-common/src/main/java/org/apache/gravitino/catalog/jdbc/converter/JdbcExceptionConverter.java
+++
b/catalogs/catalog-jdbc-common/src/main/java/org/apache/gravitino/catalog/jdbc/converter/JdbcExceptionConverter.java
@@ -19,6 +19,7 @@
package org.apache.gravitino.catalog.jdbc.converter;
import java.sql.SQLException;
+import org.apache.gravitino.exceptions.ConnectionFailedException;
import org.apache.gravitino.exceptions.GravitinoRuntimeException;
import org.apache.gravitino.exceptions.NoSuchSchemaException;
import org.apache.gravitino.exceptions.NoSuchTableException;
@@ -51,6 +52,10 @@ public class JdbcExceptionConverter {
case 1051:
return new NoSuchTableException(sqlException,
sqlException.getMessage());
default:
+ if (sqlException.getMessage() != null
+ && sqlException.getMessage().contains("Access denied")) {
+ return new ConnectionFailedException(sqlException,
sqlException.getMessage());
+ }
return new GravitinoRuntimeException(sqlException,
sqlException.getMessage());
}
}
diff --git
a/catalogs/catalog-jdbc-doris/src/main/java/org/apache/gravitino/catalog/doris/converter/DorisExceptionConverter.java
b/catalogs/catalog-jdbc-doris/src/main/java/org/apache/gravitino/catalog/doris/converter/DorisExceptionConverter.java
index 9c1cc11a2..ccdd4c7da 100644
---
a/catalogs/catalog-jdbc-doris/src/main/java/org/apache/gravitino/catalog/doris/converter/DorisExceptionConverter.java
+++
b/catalogs/catalog-jdbc-doris/src/main/java/org/apache/gravitino/catalog/doris/converter/DorisExceptionConverter.java
@@ -22,6 +22,7 @@ import com.google.common.annotations.VisibleForTesting;
import java.sql.SQLException;
import java.util.regex.Pattern;
import org.apache.gravitino.catalog.jdbc.converter.JdbcExceptionConverter;
+import org.apache.gravitino.exceptions.ConnectionFailedException;
import org.apache.gravitino.exceptions.GravitinoRuntimeException;
import org.apache.gravitino.exceptions.NoSuchColumnException;
import org.apache.gravitino.exceptions.NoSuchPartitionException;
@@ -109,6 +110,9 @@ public class DorisExceptionConverter extends
JdbcExceptionConverter {
case CODE_PARTITION_ALREADY_EXISTS:
return new PartitionAlreadyExistsException(se, se.getMessage());
default:
+ if (se.getMessage() != null && se.getMessage().contains("Access
denied")) {
+ return new ConnectionFailedException(se, se.getMessage());
+ }
return new GravitinoRuntimeException(se, se.getMessage());
}
}
diff --git
a/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/integration/test/CatalogDorisIT.java
b/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/integration/test/CatalogDorisIT.java
index 96b92b696..ca04c03c4 100644
---
a/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/integration/test/CatalogDorisIT.java
+++
b/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/integration/test/CatalogDorisIT.java
@@ -42,6 +42,7 @@ import org.apache.gravitino.Schema;
import org.apache.gravitino.SupportsSchemas;
import org.apache.gravitino.catalog.jdbc.config.JdbcConfig;
import org.apache.gravitino.client.GravitinoMetalake;
+import org.apache.gravitino.exceptions.ConnectionFailedException;
import org.apache.gravitino.exceptions.NoSuchPartitionException;
import org.apache.gravitino.exceptions.NoSuchSchemaException;
import org.apache.gravitino.exceptions.SchemaAlreadyExistsException;
@@ -110,6 +111,7 @@ public class CatalogDorisIT extends BaseIT {
private static final ContainerSuite containerSuite =
ContainerSuite.getInstance();
private GravitinoMetalake metalake;
+ private String jdbcUrl;
protected Catalog catalog;
@@ -155,7 +157,7 @@ public class CatalogDorisIT extends BaseIT {
DorisContainer dorisContainer = containerSuite.getDorisContainer();
- String jdbcUrl =
+ jdbcUrl =
String.format(
"jdbc:mysql://%s:%d/",
dorisContainer.getContainerIpAddress(),
DorisContainer.FE_MYSQL_PORT);
@@ -462,6 +464,27 @@ public class CatalogDorisIT extends BaseIT {
IllegalArgumentException.class, () ->
catalog.asTableCatalog().dropTable(tableIdentifier4));
}
+ @Test
+ void testTestConnection() {
+ Map<String, String> catalogProperties = Maps.newHashMap();
+ catalogProperties.put(JdbcConfig.JDBC_URL.getKey(), jdbcUrl);
+ catalogProperties.put(JdbcConfig.JDBC_DRIVER.getKey(), DRIVER_CLASS_NAME);
+ catalogProperties.put(JdbcConfig.USERNAME.getKey(),
DorisContainer.USER_NAME);
+ catalogProperties.put(JdbcConfig.PASSWORD.getKey(), "wrong_password");
+
+ Exception exception =
+ assertThrows(
+ ConnectionFailedException.class,
+ () ->
+ metalake.testConnection(
+ GravitinoITUtils.genRandomName("doris_it_catalog"),
+ Catalog.Type.RELATIONAL,
+ provider,
+ "doris catalog comment",
+ catalogProperties));
+ Assertions.assertTrue(exception.getMessage().contains("Access denied for
user"));
+ }
+
@Test
void testAlterDorisTable() {
// create a table
diff --git
a/catalogs/catalog-jdbc-mysql/src/test/java/org/apache/gravitino/catalog/mysql/integration/test/CatalogMysqlIT.java
b/catalogs/catalog-jdbc-mysql/src/test/java/org/apache/gravitino/catalog/mysql/integration/test/CatalogMysqlIT.java
index 4d4237d72..6b8c824d0 100644
---
a/catalogs/catalog-jdbc-mysql/src/test/java/org/apache/gravitino/catalog/mysql/integration/test/CatalogMysqlIT.java
+++
b/catalogs/catalog-jdbc-mysql/src/test/java/org/apache/gravitino/catalog/mysql/integration/test/CatalogMysqlIT.java
@@ -45,6 +45,7 @@ import org.apache.gravitino.auth.AuthConstants;
import org.apache.gravitino.catalog.jdbc.config.JdbcConfig;
import
org.apache.gravitino.catalog.mysql.integration.test.service.MysqlService;
import org.apache.gravitino.client.GravitinoMetalake;
+import org.apache.gravitino.exceptions.ConnectionFailedException;
import org.apache.gravitino.exceptions.NoSuchSchemaException;
import org.apache.gravitino.exceptions.NotFoundException;
import org.apache.gravitino.exceptions.SchemaAlreadyExistsException;
@@ -256,6 +257,34 @@ public class CatalogMysqlIT extends BaseIT {
return properties;
}
+ @Test
+ void testTestConnection() throws SQLException {
+ Map<String, String> catalogProperties = Maps.newHashMap();
+
+ catalogProperties.put(
+ JdbcConfig.JDBC_URL.getKey(),
+ StringUtils.substring(
+ MYSQL_CONTAINER.getJdbcUrl(TEST_DB_NAME),
+ 0,
+ MYSQL_CONTAINER.getJdbcUrl(TEST_DB_NAME).lastIndexOf("/")));
+ catalogProperties.put(
+ JdbcConfig.JDBC_DRIVER.getKey(),
MYSQL_CONTAINER.getDriverClassName(TEST_DB_NAME));
+ catalogProperties.put(JdbcConfig.USERNAME.getKey(),
MYSQL_CONTAINER.getUsername());
+ catalogProperties.put(JdbcConfig.PASSWORD.getKey(), "wrong_password");
+
+ Exception exception =
+ assertThrows(
+ ConnectionFailedException.class,
+ () ->
+ metalake.testConnection(
+ GravitinoITUtils.genRandomName("mysql_it_catalog"),
+ Catalog.Type.RELATIONAL,
+ provider,
+ "comment",
+ catalogProperties));
+ Assertions.assertTrue(exception.getMessage().contains("Access denied for
user"));
+ }
+
@Test
void testOperationMysqlSchema() {
SupportsSchemas schemas = catalog.asSchemas();
diff --git
a/catalogs/catalog-jdbc-oceanbase/src/test/java/org/apache/gravitino/catalog/oceanbase/integration/test/CatalogOceanBaseIT.java
b/catalogs/catalog-jdbc-oceanbase/src/test/java/org/apache/gravitino/catalog/oceanbase/integration/test/CatalogOceanBaseIT.java
index edcc9354b..4b5181c74 100644
---
a/catalogs/catalog-jdbc-oceanbase/src/test/java/org/apache/gravitino/catalog/oceanbase/integration/test/CatalogOceanBaseIT.java
+++
b/catalogs/catalog-jdbc-oceanbase/src/test/java/org/apache/gravitino/catalog/oceanbase/integration/test/CatalogOceanBaseIT.java
@@ -43,6 +43,7 @@ import org.apache.gravitino.auth.AuthConstants;
import org.apache.gravitino.catalog.jdbc.config.JdbcConfig;
import
org.apache.gravitino.catalog.oceanbase.integration.test.service.OceanBaseService;
import org.apache.gravitino.client.GravitinoMetalake;
+import org.apache.gravitino.exceptions.ConnectionFailedException;
import org.apache.gravitino.exceptions.NoSuchSchemaException;
import org.apache.gravitino.exceptions.NotFoundException;
import org.apache.gravitino.exceptions.SchemaAlreadyExistsException;
@@ -322,6 +323,34 @@ public class CatalogOceanBaseIT extends BaseIT {
Assertions.assertTrue(schemaNames.contains(schemaName));
}
+ @Test
+ void testTestConnection() throws SQLException {
+ Map<String, String> catalogProperties = Maps.newHashMap();
+
+ catalogProperties.put(
+ JdbcConfig.JDBC_URL.getKey(),
+ StringUtils.substring(
+ OCEANBASE_CONTAINER.getJdbcUrl(TEST_DB_NAME),
+ 0,
+ OCEANBASE_CONTAINER.getJdbcUrl(TEST_DB_NAME).lastIndexOf("/")));
+ catalogProperties.put(
+ JdbcConfig.JDBC_DRIVER.getKey(),
OCEANBASE_CONTAINER.getDriverClassName(TEST_DB_NAME));
+ catalogProperties.put(JdbcConfig.USERNAME.getKey(),
OCEANBASE_CONTAINER.getUsername());
+ catalogProperties.put(JdbcConfig.PASSWORD.getKey(), "wrong_password");
+
+ Exception exception =
+ assertThrows(
+ ConnectionFailedException.class,
+ () ->
+ metalake.testConnection(
+ GravitinoITUtils.genRandomName("oceanbase_it_catalog"),
+ Catalog.Type.RELATIONAL,
+ provider,
+ "comment",
+ catalogProperties));
+ Assertions.assertTrue(exception.getMessage().contains("Access denied for
user"));
+ }
+
@Test
void testCreateAndLoadOceanBaseTable() {
// Create table from Gravitino API
diff --git
a/catalogs/catalog-jdbc-postgresql/src/main/java/org/apache/gravitino/catalog/postgresql/converter/PostgreSqlExceptionConverter.java
b/catalogs/catalog-jdbc-postgresql/src/main/java/org/apache/gravitino/catalog/postgresql/converter/PostgreSqlExceptionConverter.java
index d9931bbd7..4bae02cf7 100644
---
a/catalogs/catalog-jdbc-postgresql/src/main/java/org/apache/gravitino/catalog/postgresql/converter/PostgreSqlExceptionConverter.java
+++
b/catalogs/catalog-jdbc-postgresql/src/main/java/org/apache/gravitino/catalog/postgresql/converter/PostgreSqlExceptionConverter.java
@@ -20,6 +20,7 @@ package org.apache.gravitino.catalog.postgresql.converter;
import java.sql.SQLException;
import org.apache.gravitino.catalog.jdbc.converter.JdbcExceptionConverter;
+import org.apache.gravitino.exceptions.ConnectionFailedException;
import org.apache.gravitino.exceptions.GravitinoRuntimeException;
import org.apache.gravitino.exceptions.NoSuchSchemaException;
import org.apache.gravitino.exceptions.NoSuchTableException;
@@ -47,6 +48,9 @@ public class PostgreSqlExceptionConverter extends
JdbcExceptionConverter {
return new GravitinoRuntimeException(se.getMessage(), se);
}
} else {
+ if (se.getMessage() != null && se.getMessage().contains("password
authentication failed")) {
+ return new ConnectionFailedException(se.getMessage(), se);
+ }
return new GravitinoRuntimeException(se.getMessage(), se);
}
}
diff --git
a/catalogs/catalog-jdbc-postgresql/src/test/java/org/apache/gravitino/catalog/postgresql/integration/test/CatalogPostgreSqlIT.java
b/catalogs/catalog-jdbc-postgresql/src/test/java/org/apache/gravitino/catalog/postgresql/integration/test/CatalogPostgreSqlIT.java
index f22073c78..558775014 100644
---
a/catalogs/catalog-jdbc-postgresql/src/test/java/org/apache/gravitino/catalog/postgresql/integration/test/CatalogPostgreSqlIT.java
+++
b/catalogs/catalog-jdbc-postgresql/src/test/java/org/apache/gravitino/catalog/postgresql/integration/test/CatalogPostgreSqlIT.java
@@ -44,6 +44,7 @@ import org.apache.gravitino.auth.AuthConstants;
import org.apache.gravitino.catalog.jdbc.config.JdbcConfig;
import
org.apache.gravitino.catalog.postgresql.integration.test.service.PostgreSqlService;
import org.apache.gravitino.client.GravitinoMetalake;
+import org.apache.gravitino.exceptions.ConnectionFailedException;
import org.apache.gravitino.exceptions.NoSuchSchemaException;
import org.apache.gravitino.exceptions.SchemaAlreadyExistsException;
import org.apache.gravitino.integration.test.container.ContainerSuite;
@@ -239,6 +240,32 @@ public class CatalogPostgreSqlIT extends BaseIT {
};
}
+ @Test
+ void testTestConnection() throws SQLException {
+ Map<String, String> catalogProperties = Maps.newHashMap();
+
+ String jdbcUrl = POSTGRESQL_CONTAINER.getJdbcUrl(TEST_DB_NAME);
+ catalogProperties.put(
+ JdbcConfig.JDBC_DRIVER.getKey(),
POSTGRESQL_CONTAINER.getDriverClassName(TEST_DB_NAME));
+ catalogProperties.put(JdbcConfig.JDBC_URL.getKey(), jdbcUrl);
+ catalogProperties.put(JdbcConfig.JDBC_DATABASE.getKey(),
TEST_DB_NAME.toString());
+ catalogProperties.put(JdbcConfig.USERNAME.getKey(),
POSTGRESQL_CONTAINER.getUsername());
+ catalogProperties.put(JdbcConfig.PASSWORD.getKey(), "wrong_password");
+
+ Exception exception =
+ assertThrows(
+ ConnectionFailedException.class,
+ () ->
+ metalake.testConnection(
+ GravitinoITUtils.genRandomName("postgresql_it_catalog"),
+ Catalog.Type.RELATIONAL,
+ provider,
+ "comment",
+ catalogProperties));
+ Assertions.assertTrue(
+ exception.getMessage().contains("password authentication failed for
user"));
+ }
+
@Test
void testCreateTableWithArrayType() {
String tableName =
GravitinoITUtils.genRandomName("postgresql_it_array_table");
diff --git
a/catalogs/catalog-lakehouse-iceberg/src/test/java/org/apache/gravitino/catalog/lakehouse/iceberg/integration/test/TestMultipleJDBCLoad.java
b/catalogs/catalog-lakehouse-iceberg/src/test/java/org/apache/gravitino/catalog/lakehouse/iceberg/integration/test/TestMultipleJDBCLoad.java
index 4b1edae82..40e437a0f 100644
---
a/catalogs/catalog-lakehouse-iceberg/src/test/java/org/apache/gravitino/catalog/lakehouse/iceberg/integration/test/TestMultipleJDBCLoad.java
+++
b/catalogs/catalog-lakehouse-iceberg/src/test/java/org/apache/gravitino/catalog/lakehouse/iceberg/integration/test/TestMultipleJDBCLoad.java
@@ -31,6 +31,7 @@ import java.util.Map;
import org.apache.gravitino.Catalog;
import org.apache.gravitino.NameIdentifier;
import org.apache.gravitino.client.GravitinoMetalake;
+import org.apache.gravitino.exceptions.ConnectionFailedException;
import org.apache.gravitino.iceberg.common.IcebergConfig;
import org.apache.gravitino.integration.test.container.MySQLContainer;
import org.apache.gravitino.integration.test.container.PostgreSQLContainer;
@@ -96,8 +97,24 @@ public class TestMultipleJDBCLoad extends BaseIT {
icebergMysqlConf.put(
IcebergConfig.JDBC_DRIVER.getKey(),
mySQLContainer.getDriverClassName(TEST_DB_NAME));
icebergMysqlConf.put(GRAVITINO_JDBC_USER, mySQLContainer.getUsername());
- icebergMysqlConf.put(GRAVITINO_JDBC_PASSWORD,
mySQLContainer.getPassword());
+ icebergMysqlConf.put(GRAVITINO_JDBC_PASSWORD, "wrong_password");
String mysqlCatalogName =
RandomNameUtils.genRandomName("it_iceberg_mysql");
+
+ // test wrong password
+ Exception exception =
+ Assertions.assertThrows(
+ ConnectionFailedException.class,
+ () ->
+ metalake.testConnection(
+ mysqlCatalogName,
+ Catalog.Type.RELATIONAL,
+ "lakehouse-iceberg",
+ "comment",
+ icebergMysqlConf));
+ Assertions.assertTrue(exception.getMessage().contains("Access denied for
user"));
+
+ // test correct password
+ icebergMysqlConf.put(GRAVITINO_JDBC_PASSWORD,
mySQLContainer.getPassword());
Catalog mysqlCatalog =
metalake.createCatalog(
mysqlCatalogName,
diff --git
a/catalogs/catalog-lakehouse-paimon/src/main/java/org/apache/gravitino/catalog/lakehouse/paimon/utils/CatalogUtils.java
b/catalogs/catalog-lakehouse-paimon/src/main/java/org/apache/gravitino/catalog/lakehouse/paimon/utils/CatalogUtils.java
index 46671e12e..3ae48576c 100644
---
a/catalogs/catalog-lakehouse-paimon/src/main/java/org/apache/gravitino/catalog/lakehouse/paimon/utils/CatalogUtils.java
+++
b/catalogs/catalog-lakehouse-paimon/src/main/java/org/apache/gravitino/catalog/lakehouse/paimon/utils/CatalogUtils.java
@@ -30,6 +30,7 @@ import static
org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY
import com.google.common.base.Preconditions;
import java.io.File;
+import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
@@ -39,6 +40,7 @@ import
org.apache.gravitino.catalog.lakehouse.paimon.PaimonConfig;
import
org.apache.gravitino.catalog.lakehouse.paimon.authentication.AuthenticationConfig;
import
org.apache.gravitino.catalog.lakehouse.paimon.authentication.kerberos.KerberosClient;
import
org.apache.gravitino.catalog.lakehouse.paimon.ops.PaimonBackendCatalogWrapper;
+import org.apache.gravitino.exceptions.ConnectionFailedException;
import org.apache.hadoop.conf.Configuration;
import org.apache.paimon.catalog.Catalog;
import org.apache.paimon.catalog.CatalogContext;
@@ -103,11 +105,20 @@ public class CatalogUtils {
* @param paimonConfig The Paimon configuration.
* @return The {@link Catalog} instance of catalog backend.
*/
+ @SuppressWarnings("FormatStringAnnotation")
public static Catalog loadCatalogBackendWithSimpleAuth(PaimonConfig
paimonConfig) {
checkPaimonConfig(paimonConfig);
CatalogContext catalogContext =
CatalogContext.create(Options.fromMap(paimonConfig.getAllConfig()));
- return CatalogFactory.createCatalog(catalogContext);
+ try {
+ return CatalogFactory.createCatalog(catalogContext);
+ } catch (RuntimeException e) {
+ if (e.getCause() instanceof SQLException
+ && e.getCause().getMessage().contains("Access denied")) {
+ throw new ConnectionFailedException(e, e.getMessage());
+ }
+ throw e;
+ }
}
private static void checkPaimonConfig(PaimonConfig paimonConfig) {
diff --git
a/catalogs/catalog-lakehouse-paimon/src/test/java/org/apache/gravitino/catalog/lakehouse/paimon/integration/test/CatalogPaimonBaseIT.java
b/catalogs/catalog-lakehouse-paimon/src/test/java/org/apache/gravitino/catalog/lakehouse/paimon/integration/test/CatalogPaimonBaseIT.java
index a61702507..b2c6d624a 100644
---
a/catalogs/catalog-lakehouse-paimon/src/test/java/org/apache/gravitino/catalog/lakehouse/paimon/integration/test/CatalogPaimonBaseIT.java
+++
b/catalogs/catalog-lakehouse-paimon/src/test/java/org/apache/gravitino/catalog/lakehouse/paimon/integration/test/CatalogPaimonBaseIT.java
@@ -104,7 +104,7 @@ public abstract class CatalogPaimonBaseIT extends BaseIT {
protected String schemaName =
GravitinoITUtils.genRandomName("paimon_it_schema");
protected static final String schema_comment = "schema_comment";
- private static final String provider = "lakehouse-paimon";
+ protected static final String provider = "lakehouse-paimon";
private static final String catalog_comment = "catalog_comment";
private static final String table_comment = "table_comment";
private static final String PAIMON_COL_NAME1 = "paimon_col_name1";
@@ -116,7 +116,7 @@ public abstract class CatalogPaimonBaseIT extends BaseIT {
private static String INSERT_BATCH_WITHOUT_PARTITION_TEMPLATE = "INSERT INTO
paimon.%s VALUES %s";
private static final String SELECT_ALL_TEMPLATE = "SELECT * FROM paimon.%s";
private static final String DEFAULT_DB = "default";
- private GravitinoMetalake metalake;
+ protected GravitinoMetalake metalake;
private Map<String, String> catalogProperties;
@BeforeAll
diff --git
a/catalogs/catalog-lakehouse-paimon/src/test/java/org/apache/gravitino/catalog/lakehouse/paimon/integration/test/CatalogPaimonJdbcIT.java
b/catalogs/catalog-lakehouse-paimon/src/test/java/org/apache/gravitino/catalog/lakehouse/paimon/integration/test/CatalogPaimonJdbcIT.java
index 863ed50e3..3eb14f132 100644
---
a/catalogs/catalog-lakehouse-paimon/src/test/java/org/apache/gravitino/catalog/lakehouse/paimon/integration/test/CatalogPaimonJdbcIT.java
+++
b/catalogs/catalog-lakehouse-paimon/src/test/java/org/apache/gravitino/catalog/lakehouse/paimon/integration/test/CatalogPaimonJdbcIT.java
@@ -20,9 +20,14 @@ package
org.apache.gravitino.catalog.lakehouse.paimon.integration.test;
import com.google.common.collect.Maps;
import java.util.Map;
+import org.apache.gravitino.Catalog;
import
org.apache.gravitino.catalog.lakehouse.paimon.PaimonCatalogPropertiesMetadata;
+import org.apache.gravitino.exceptions.ConnectionFailedException;
import org.apache.gravitino.integration.test.container.HiveContainer;
+import org.apache.gravitino.integration.test.util.GravitinoITUtils;
+import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
@Tag("gravitino-docker-test")
@@ -58,4 +63,22 @@ public class CatalogPaimonJdbcIT extends CatalogPaimonBaseIT
{
return catalogProperties;
}
+
+ @Test
+ void testTestConnection() {
+ Map<String, String> props = initPaimonCatalogProperties();
+ props.put(PaimonCatalogPropertiesMetadata.GRAVITINO_JDBC_PASSWORD,
"wrong_password");
+
+ Exception exception =
+ Assertions.assertThrows(
+ ConnectionFailedException.class,
+ () ->
+ metalake.testConnection(
+ GravitinoITUtils.genRandomName("paimon_it_catalog"),
+ Catalog.Type.RELATIONAL,
+ provider,
+ null,
+ props));
+ Assertions.assertTrue(exception.getMessage().contains("Access denied for
user"));
+ }
}
diff --git
a/common/src/main/java/org/apache/gravitino/dto/responses/ErrorResponse.java
b/common/src/main/java/org/apache/gravitino/dto/responses/ErrorResponse.java
index c68b71f13..015743bbf 100644
--- a/common/src/main/java/org/apache/gravitino/dto/responses/ErrorResponse.java
+++ b/common/src/main/java/org/apache/gravitino/dto/responses/ErrorResponse.java
@@ -235,7 +235,7 @@ public class ErrorResponse extends BaseResponse {
}
/**
- * Create a new entity in use error instance of {@link ErrorResponse}.
+ * Create a new not in use error instance of {@link ErrorResponse}.
*
* @param type The type of the error.
* @param message The message of the error.
@@ -295,7 +295,7 @@ public class ErrorResponse extends BaseResponse {
}
/**
- * Create a new unknown error instance of {@link ErrorResponse}.
+ * Create a new oauth error instance of {@link ErrorResponse}.
*
* @param code The code of the error.
* @param type The type of the error.
diff --git
a/iceberg/iceberg-common/src/main/java/org/apache/gravitino/iceberg/common/utils/IcebergCatalogUtil.java
b/iceberg/iceberg-common/src/main/java/org/apache/gravitino/iceberg/common/utils/IcebergCatalogUtil.java
index 4e28eb7c8..a2402082f 100644
---
a/iceberg/iceberg-common/src/main/java/org/apache/gravitino/iceberg/common/utils/IcebergCatalogUtil.java
+++
b/iceberg/iceberg-common/src/main/java/org/apache/gravitino/iceberg/common/utils/IcebergCatalogUtil.java
@@ -25,11 +25,13 @@ import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import java.io.File;
import java.io.IOException;
+import java.sql.SQLException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import org.apache.gravitino.catalog.lakehouse.iceberg.IcebergConstants;
+import org.apache.gravitino.exceptions.ConnectionFailedException;
import org.apache.gravitino.iceberg.common.ClosableHiveCatalog;
import org.apache.gravitino.iceberg.common.IcebergCatalogBackend;
import org.apache.gravitino.iceberg.common.IcebergConfig;
@@ -44,6 +46,7 @@ import org.apache.iceberg.catalog.Catalog;
import org.apache.iceberg.hive.HiveCatalog;
import org.apache.iceberg.inmemory.InMemoryCatalog;
import org.apache.iceberg.jdbc.JdbcCatalog;
+import org.apache.iceberg.jdbc.UncheckedSQLException;
import org.apache.iceberg.rest.RESTCatalog;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -112,6 +115,7 @@ public class IcebergCatalogUtil {
}
}
+ @SuppressWarnings("FormatStringAnnotation")
private static JdbcCatalog loadJdbcCatalog(IcebergConfig icebergConfig) {
String driverClassName = icebergConfig.getJdbcDriver();
String icebergCatalogName = icebergConfig.getCatalogBackendName();
@@ -135,7 +139,15 @@ public class IcebergCatalogUtil {
HdfsConfiguration hdfsConfiguration = new HdfsConfiguration();
properties.forEach(hdfsConfiguration::set);
jdbcCatalog.setConf(hdfsConfiguration);
- jdbcCatalog.initialize(icebergCatalogName, properties);
+ try {
+ jdbcCatalog.initialize(icebergCatalogName, properties);
+ } catch (UncheckedSQLException e) {
+ if (e.getCause() instanceof SQLException
+ && e.getCause().getMessage().contains("Access denied")) {
+ throw new ConnectionFailedException(e, e.getMessage());
+ }
+ throw e;
+ }
return jdbcCatalog;
}