diff --git a/pom.xml b/pom.xml
index d426e03..4ff339c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -16,7 +16,7 @@
+ * Provides support for accessing Db2 databases using credentials stored within AWS Secrets Manager. + *
+ * + *+ * Configuration properties are specified using the "db2" subprefix (e.g drivers.mysql.realDriverClass). + *
+ */ +public final class AWSSecretsManagerDb2Driver extends AWSSecretsManagerDriver { + + /** + * The Db2 error code for when a user logs in using an invalid password. + * + * See Db2 error codes. + */ + public static final int ACCESS_DENIED_FOR_USER_USING_PASSWORD_TO_DATABASE = -1403; + + /** + * Set to Db2. + */ + public static final String SUBPREFIX = "db2"; + + static { + AWSSecretsManagerDriver.register(new AWSSecretsManagerDb2Driver()); + } + + /** + * Constructs the driver setting the properties from the properties file using system properties as defaults. + * Instantiates the secret cache with default options. + */ + public AWSSecretsManagerDb2Driver() { + super(); + } + + /** + * Constructs the driver setting the properties from the properties file using system properties as defaults. + * Uses the passed in SecretCache. + * + * @param cache Secret cache to use to retrieve secrets + */ + public AWSSecretsManagerDb2Driver(SecretCache cache) { + super(cache); + } + + /** + * Constructs the driver setting the properties from the properties file using system properties as defaults. + * Instantiates the secret cache with the passed in client builder. + * + * @param builder Builder used to instantiate cache + */ + public AWSSecretsManagerDb2Driver(AWSSecretsManagerClientBuilder builder) { + super(builder); + } + + /** + * Constructs the driver setting the properties from the properties file using system properties as defaults. + * Instantiates the secret cache with the provided AWS Secrets Manager client. + * + * @param client AWS Secrets Manager client to instantiate cache + */ + public AWSSecretsManagerDb2Driver(AWSSecretsManager client) { + super(client); + } + + /** + * Constructs the driver setting the properties from the properties file using system properties as defaults. + * Instantiates the secret cache with the provided cache configuration. + * + * @param cacheConfig Cache configuration to instantiate cache + */ + public AWSSecretsManagerDb2Driver(SecretCacheConfiguration cacheConfig) { + super(cacheConfig); + } + + @Override + public String getPropertySubprefix() { + return SUBPREFIX; + } + + @Override + public boolean isExceptionDueToAuthenticationError(Exception e) { + return SQLExceptionUtils.unwrapAndCheckForCode(e, ACCESS_DENIED_FOR_USER_USING_PASSWORD_TO_DATABASE); + } + + @Override + public String constructUrlFromEndpointPortDatabase(String endpoint, String port, String dbname) { + String url = "jdbc:db2://" + endpoint; + if (!StringUtils.isNullOrEmpty(port)) { + url += ":" + port; + } + if (!StringUtils.isNullOrEmpty(dbname)) { + url += "/" + dbname; + } + return url; + } + + @Override + public String getDefaultDriverClass() { + try { + Class.forName("com.ibm.db2.jcc.DB2Driver", false, this.getClass().getClassLoader()); + return "com.ibm.db2.jcc.DB2Driver"; + } catch (ClassNotFoundException e) { + return "com.ibm.db2.jcc.DB2Driver"; + } + } +} diff --git a/src/test/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerDb2DriverTest.java b/src/test/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerDb2DriverTest.java new file mode 100644 index 0000000..c053012 --- /dev/null +++ b/src/test/java/com/amazonaws/secretsmanager/sql/AWSSecretsManagerDb2DriverTest.java @@ -0,0 +1,107 @@ +/* + * Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file 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 com.amazonaws.secretsmanager.sql; + +import com.amazonaws.secretsmanager.caching.SecretCache; +import com.amazonaws.secretsmanager.util.TestClass; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.sql.SQLException; + +import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * Tests for the Db2 Driver. + */ +@RunWith(PowerMockRunner.class) +@SuppressStaticInitializationFor("com.amazonaws.secretsmanager.sql.AWSSecretsManagerDb2Driver") +@PowerMockIgnore("jdk.internal.reflect.*") +public class AWSSecretsManagerDb2DriverTest extends TestClass { + + private AWSSecretsManagerDb2Driver sut; + + @Mock + private SecretCache cache; + + @Before + public void setup() { + System.setProperty("drivers.db2.realDriverClass", "com.amazonaws.secretsmanager.sql.DummyDriver"); + MockitoAnnotations.initMocks(this); + try { + sut = new AWSSecretsManagerDb2Driver(cache); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Test + public void test_getPropertySubprefix() { + assertEquals("db2", sut.getPropertySubprefix()); + } + + @Test + public void test_isExceptionDueToAuthenticationError_returnsTrue_correctException() { + SQLException e = new SQLException("", "", -1403); + + assertTrue(sut.isExceptionDueToAuthenticationError(e)); + } + + @Test + public void test_isExceptionDueToAuthenticationError_returnsFalse_wrongSQLException() { + SQLException e = new SQLException("", "", -2323); + + assertFalse(sut.isExceptionDueToAuthenticationError(e)); + } + + @Test + public void test_isExceptionDueToAuthenticationError_returnsFalse_runtimeException() { + RuntimeException e = new RuntimeException("asdf"); + + assertFalse(sut.isExceptionDueToAuthenticationError(e)); + } + + @Test + public void test_constructUrl() { + String url = sut.constructUrlFromEndpointPortDatabase("test-endpoint", "1234", "dev"); + assertEquals(url, "jdbc:db2://test-endpoint:1234/dev"); + } + + @Test + public void test_constructUrlNullPort() { + String url = sut.constructUrlFromEndpointPortDatabase("test-endpoint", null, "dev"); + assertEquals(url, "jdbc:db2://test-endpoint/dev"); + } + + @Test + public void test_constructUrlNullDatabase() { + String url = sut.constructUrlFromEndpointPortDatabase("test-endpoint", "1234", null); + assertEquals(url, "jdbc:db2://test-endpoint:1234"); + } + + @Test + public void test_getDefaultDriverClass() { + System.clearProperty("drivers.db2.realDriverClass"); + AWSSecretsManagerDb2Driver sut2 = new AWSSecretsManagerDb2Driver(cache); + assertEquals(getFieldFrom(sut2, "realDriverClass"), sut2.getDefaultDriverClass()); + } +}