chore: better error handling in SQL Stored proc...
...edure verifier
This examines the SQLSTATE to determine the cause of SQLException thrown
when the connection attempt is made.
Also adds check for required `user` and `password` parameters and
logging of SQL exception for easier troubleshooting.
@@ -20,15 +20,20 @@ import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.Map;
import org.apache.camel.component.extension.verifier.DefaultComponentVerifierExtension;
import org.apache.camel.component.extension.verifier.ResultBuilder;
import org.apache.camel.component.extension.verifier.ResultErrorBuilder;
import org.apache.camel.component.extension.verifier.ResultErrorHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class SqlStoredConnectorVerifierExtension extends DefaultComponentVerifierExtension {
+ private static final Logger LOG = LoggerFactory.getLogger(SqlStoredConnectorVerifierExtension.class);
+
public SqlStoredConnectorVerifierExtension() {
super("sql-stored-connector");
}
@@ -44,8 +49,9 @@ public class SqlStoredConnectorVerifierExtension extends DefaultComponentVerifie
@Override
protected Result verifyParameters(Map<String, Object> parameters) {
ResultBuilder builder = ResultBuilder.withStatusAndScope(Result.Status.OK, Scope.PARAMETERS)
- .error(ResultErrorHelper.requiresOption("url", parameters));
-
+ .error(ResultErrorHelper.requiresOption("url", parameters))
+ .error(ResultErrorHelper.requiresOption("user", parameters))
+ .error(ResultErrorHelper.requiresOption("password", parameters));
if (builder.build().getErrors().isEmpty()) {
try (Connection connection =
@@ -53,7 +59,44 @@ public class SqlStoredConnectorVerifierExtension extends DefaultComponentVerifie
parameters.get("url").toString(),
String.valueOf(parameters.get("user")),
String.valueOf(parameters.get("password")))) {
+ // just try to get the connection
} catch (SQLException e) {
+ final Map<String, Object> redacted = new HashMap<>(parameters);
+ redacted.replace("password", "********");
+ LOG.warn("Unable to connecto to database with parameters {}, SQLSTATE: {}, error code: {}",
+ redacted, e.getSQLState(), e.getErrorCode(), e);
+
+ final String sqlState = e.getSQLState();
+ if (sqlState == null || sqlState.length() < 2) {
+ unsupportedDatabase(builder);
+ } else {
+ switch (sqlState.substring(0, 2)) {
+ case "28":
+ builder.error(ResultErrorBuilder.withCodeAndDescription(VerificationError.StandardCode.AUTHENTICATION, e.getMessage())
+ .parameterKey("user")
+ .parameterKey("password")
+ .build());
+ break;
+ case "08":
+ case "3D":
+ builder.error(ResultErrorBuilder.withCodeAndDescription(
+ VerificationError.StandardCode.ILLEGAL_PARAMETER_VALUE, e.getMessage())
+ .parameterKey("url")
+ .build());
+ break;
+ default:
+ builder.error(ResultErrorBuilder.withCodeAndDescription(
+ VerificationError.StandardCode.GENERIC, e.getMessage())
+ .build());
+ break;
+ }
+ }
+ }
+ }
+ return builder.build();
+ }
+
+ private static void unsupportedDatabase(ResultBuilder builder) {
String supportedDatabases = String.join(",",
Arrays.stream(DatabaseProduct.values())
.map(Enum::name)
@@ -63,10 +106,6 @@ public class SqlStoredConnectorVerifierExtension extends DefaultComponentVerifie
VerificationError.StandardCode.UNSUPPORTED,
msg).build()).build();
}
- }
- return builder.build();
-
- }
// *********************************
// Connectivity validation
