Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Redshift driver #68

Merged
merged 1 commit into from
May 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: Java Build

on: [push]

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- name: Set up JDK 11
uses: actions/setup-java@v3
with:
java-version: '11'
distribution: 'adopt'
- name: Build with Maven
run: mvn --batch-mode --update-snapshots package
20 changes: 20 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
# https://github.com/takari/maven-wrapper#usage-without-binary-jar
.mvn/wrapper/maven-wrapper.jar

# Eclipse m2e generated files
# Eclipse Core
.project
# JDT-specific (Eclipse Java Development Tools)
.classpath

# VS Code
.vscode/
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# AWS Secrets Manager JDBC Library

![build](https://github.com/aws/aws-secretsmanager-jdbc/actions/workflows/CI.yml/badge.svg)

The **AWS Secrets Manager JDBC Library** enables Java developers to easily connect to SQL databases using secrets stored in AWS Secrets Manager.

## License
Expand All @@ -22,7 +24,7 @@ The recommended way to use the SQL Connection Library is to consume it from Mave
<dependency>
<groupId>com.amazonaws.secretsmanager</groupId>
<artifactId>aws-secretsmanager-jdbc</artifactId>
<version>1.0.7</version>
<version>1.0.8</version>
</dependency>
```

Expand Down
17 changes: 8 additions & 9 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,13 @@
~ CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
~ and limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.amazonaws.secretsmanager</groupId>
<artifactId>aws-secretsmanager-jdbc</artifactId>
<packaging>jar</packaging>
<name>AWS Secrets Manager SQL Connection Library</name>
<version>1.0.7</version>
<version>1.0.8</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 All @@ -27,16 +25,17 @@
<properties>
<aws-java-sdk.version>1.12.148</aws-java-sdk.version>
<aws-secretsmanager-cache.version>1.0.2</aws-secretsmanager-cache.version>
<lombok.version>1.16.20</lombok.version>
<jackson.version>2.10.5.1</jackson.version>
<junit.version>4.11</junit.version>
<lombok.version>1.18.24</lombok.version>
<jackson.version>2.13.2.2</jackson.version>
<junit.version>4.13.1</junit.version>
<mockito.version>1.10.19</mockito.version>
<powermock.version>1.6.6</powermock.version>
<compiler.plugin.version>3.2</compiler.plugin.version>
<javadoc.plugin.version>3.0.1</javadoc.plugin.version>
<source.plugin.version>3.0.1</source.plugin.version>
<checkstyle.plugin.version>2.17</checkstyle.plugin.version>
<findbugs.plugin.version>3.0.4</findbugs.plugin.version>
<findbugs.plugin.version>3.0.5</findbugs.plugin.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<licenses>
Expand Down Expand Up @@ -244,4 +243,4 @@
</build>
</profile>
</profiles>
</project>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
/*
* 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 java.sql.SQLException;

import com.amazonaws.secretsmanager.caching.SecretCache;
import com.amazonaws.secretsmanager.caching.SecretCacheConfiguration;
import com.amazonaws.services.secretsmanager.AWSSecretsManager;
import com.amazonaws.services.secretsmanager.AWSSecretsManagerClientBuilder;
import com.amazonaws.util.StringUtils;

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

/**
* The Redshift error code for when a user logs in using an invalid password.
*
* See <a href=
* "https://www.postgresql.org/docs/9.6/static/errcodes-appendix.html">Postgres documentation</a> (Redshift is built on Postgres).
*/
public static final String ACCESS_DENIED_FOR_USER_USING_PASSWORD_TO_DATABASE = "28P01";

public static final String SUBPREFIX = "redshift";

static {
AWSSecretsManagerDriver.register(new AWSSecretsManagerRedshiftDriver());
}

/**
* Constructs the driver setting the properties from the properties file using
* system properties as defaults.
* Instantiates the secret cache with default options.
*/
public AWSSecretsManagerRedshiftDriver() {
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 AWSSecretsManagerRedshiftDriver(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 AWSSecretsManagerRedshiftDriver(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 AWSSecretsManagerRedshiftDriver(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 AWSSecretsManagerRedshiftDriver(SecretCacheConfiguration cacheConfig) {
super(cacheConfig);
}

@Override
public String getPropertySubprefix() {
return SUBPREFIX;
}

@Override
public boolean isExceptionDueToAuthenticationError(Exception e) {
if (e instanceof SQLException) {
SQLException sqle = (SQLException) e;
String sqlState = sqle.getSQLState();
return sqlState.equals(ACCESS_DENIED_FOR_USER_USING_PASSWORD_TO_DATABASE);
}
return false;
}

@Override
public String constructUrlFromEndpointPortDatabase(String endpoint, String port, String dbname) {
String url = "jdbc:redshift://" + endpoint;
if (!StringUtils.isNullOrEmpty(port)) {
url += ":" + port;
}
if (!StringUtils.isNullOrEmpty(dbname)) {
url += "/" + dbname;
}
return url;
}

@Override
public String getDefaultDriverClass() {
return "com.amazon.redshift.jdbc42.Driver";
}
}
7 changes: 5 additions & 2 deletions src/main/java/com/amazonaws/secretsmanager/util/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,11 @@ private Config(String prefix, Properties config) {
private static Properties loadPropertiesFromConfigFile(String resourceName) {
Properties newConfig = new Properties(System.getProperties());

try (InputStream configFile = ClassLoader.getSystemResourceAsStream(resourceName)) {
if (configFile != null) {
InputStream configFile;

try {
configFile = ClassLoader.getSystemResourceAsStream(resourceName);
if(configFile != null) {
newConfig.load(configFile);
configFile.close();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor;
import org.powermock.modules.junit4.PowerMockRunner;
import org.junit.Before;
Expand All @@ -42,11 +43,8 @@
* the file.
*/
@RunWith(PowerMockRunner.class)
@SuppressStaticInitializationFor({"com.amazonaws.secretsmanager.sql.AWSSecretsManagerMSSQLServerDriver",
"com.amazonaws.secretsmanager.sql.AWSSecretsManagerMariaDBDriver",
"com.amazonaws.secretsmanager.sql.AWSSecretsManagerMySQLDriver",
"com.amazonaws.secretsmanager.sql.AWSSecretsManagerOracleDriver",
"com.amazonaws.secretsmanager.sql.AWSSecretsManagerPostgreSQLDriver"})
@SuppressStaticInitializationFor({"com.amazonaws.secretsmanager.sql.*"})
@PowerMockIgnore("jdk.internal.reflect.*")
public class AWSSecretsManagerDriverTest extends TestClass {

private AWSSecretsManagerDummyDriver sut;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
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 org.junit.Before;
Expand All @@ -32,6 +33,7 @@
*/
@RunWith(PowerMockRunner.class)
@SuppressStaticInitializationFor("com.amazonaws.secretsmanager.sql.AWSSecretsManagerMSSQLServerDriver")
@PowerMockIgnore("jdk.internal.reflect.*")
public class AWSSecretsManagerMSSQLServerDriverTest extends TestClass {

private AWSSecretsManagerMSSQLServerDriver sut;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
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 org.junit.Before;
Expand All @@ -32,6 +33,7 @@
*/
@RunWith(PowerMockRunner.class)
@SuppressStaticInitializationFor("com.amazonaws.secretsmanager.sql.AWSSecretsManagerMariaDBDriver")
@PowerMockIgnore("jdk.internal.reflect.*")
public class AWSSecretsManagerMariaDBDriverTest extends TestClass {

private AWSSecretsManagerMariaDBDriver sut;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
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 org.junit.Before;
Expand All @@ -32,6 +33,7 @@
*/
@RunWith(PowerMockRunner.class)
@SuppressStaticInitializationFor("com.amazonaws.secretsmanager.sql.AWSSecretsManagerMySQLDriver")
@PowerMockIgnore("jdk.internal.reflect.*")
public class AWSSecretsManagerMySQLDriverTest extends TestClass {

private AWSSecretsManagerMySQLDriver sut;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
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 org.junit.Before;
Expand All @@ -32,6 +33,7 @@
*/
@RunWith(PowerMockRunner.class)
@SuppressStaticInitializationFor("com.amazonaws.secretsmanager.sql.AWSSecretsManagerOracleDriver")
@PowerMockIgnore("jdk.internal.reflect.*")
public class AWSSecretsManagerOracleDriverTest extends TestClass {

private AWSSecretsManagerOracleDriver sut;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
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 org.junit.Before;
Expand All @@ -32,6 +33,7 @@
*/
@RunWith(PowerMockRunner.class)
@SuppressStaticInitializationFor("com.amazonaws.secretsmanager.sql.AWSSecretsManagerPostgreSQLDriver")
@PowerMockIgnore("jdk.internal.reflect.*")
public class AWSSecretsManagerPostgreSQLDriverTest extends TestClass {

private AWSSecretsManagerPostgreSQLDriver sut;
Expand Down
Loading