Skip to content

Commit

Permalink
Adding Secrets Manager Db2 JDBC driver (#219)
Browse files Browse the repository at this point in the history
  • Loading branch information
willtong1234 authored Dec 6, 2023
1 parent 5e7e921 commit 6073977
Show file tree
Hide file tree
Showing 3 changed files with 236 additions and 1 deletion.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<artifactId>aws-secretsmanager-jdbc</artifactId>
<packaging>jar</packaging>
<name>AWS Secrets Manager SQL Connection Library</name>
<version>1.0.13</version>
<version>1.0.14</version>
<description>The AWS Secrets Manager SQL Connection Library for Java enables Java developers to easily
connect to SQL databases using secrets stored in AWS Secrets Manager.
</description>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/*
* 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.caching.SecretCacheConfiguration;
import com.amazonaws.secretsmanager.util.SQLExceptionUtils;
import com.amazonaws.services.secretsmanager.AWSSecretsManager;
import com.amazonaws.services.secretsmanager.AWSSecretsManagerClientBuilder;
import com.amazonaws.util.StringUtils;

/**
* <p>
* Provides support for accessing Db2 databases using credentials stored within AWS Secrets Manager.
* </p>
*
* <p>
* Configuration properties are specified using the "db2" subprefix (e.g drivers.mysql.realDriverClass).
* </p>
*/
public final class AWSSecretsManagerDb2Driver extends AWSSecretsManagerDriver {

/**
* The Db2 error code for when a user logs in using an invalid password.
*
* See <a href="https://www.ibm.com/docs/en/db2-for-zos/11?topic=codes-sql-error">Db2 error codes</a>.
*/
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";
}
}
}
Original file line number Diff line number Diff line change
@@ -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());
}
}

0 comments on commit 6073977

Please sign in to comment.