Skip to content

Commit 2b34346

Browse files
authored
[b/387249832] Move Redshift URL utilities to a Util class (#681)
1 parent ff2e5f5 commit 2b34346

File tree

5 files changed

+119
-83
lines changed

5 files changed

+119
-83
lines changed

dumper/app/src/main/java/com/google/edwmigration/dumper/application/dumper/connector/redshift/AbstractRedshiftConnector.java

Lines changed: 13 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@
1717
package com.google.edwmigration.dumper.application.dumper.connector.redshift;
1818

1919
import com.google.common.base.Joiner;
20-
import com.google.common.collect.Iterables;
2120
import com.google.edwmigration.dumper.application.dumper.ConnectorArguments;
22-
import com.google.edwmigration.dumper.application.dumper.MetadataDumperUsageException;
2321
import com.google.edwmigration.dumper.application.dumper.annotations.RespectsArgumentDatabaseForConnection;
2422
import com.google.edwmigration.dumper.application.dumper.annotations.RespectsArgumentDriver;
2523
import com.google.edwmigration.dumper.application.dumper.annotations.RespectsArgumentHostUnlessUrl;
@@ -29,8 +27,8 @@
2927
import com.google.edwmigration.dumper.application.dumper.connector.AbstractJdbcConnector;
3028
import com.google.edwmigration.dumper.application.dumper.handle.Handle;
3129
import com.google.edwmigration.dumper.application.dumper.handle.JdbcHandle;
32-
import java.io.UnsupportedEncodingException;
3330
import java.sql.Driver;
31+
import java.sql.SQLException;
3432
import java.time.ZoneOffset;
3533
import java.time.format.DateTimeFormatter;
3634
import java.util.List;
@@ -69,12 +67,10 @@
6967
@RespectsArgumentJDBCUri
7068
public abstract class AbstractRedshiftConnector extends AbstractJdbcConnector {
7169

72-
@SuppressWarnings("UnusedVariable")
7370
private static final Logger LOG = LoggerFactory.getLogger(AbstractRedshiftConnector.class);
7471

7572
protected static final DateTimeFormatter SQL_FORMAT =
7673
DateTimeFormatter.ISO_OFFSET_DATE_TIME.withZone(ZoneOffset.UTC);
77-
public static final int OPT_PORT_DEFAULT = 5439;
7874

7975
@Nonnull
8076
protected static CharSequence newWhereClause(List<String> clauseList, String... clauseArray) {
@@ -130,85 +126,15 @@ protected static CharSequence newWhereClause(List<String> clauseList, String...
130126
*
131127
* https://s3.amazonaws.com/redshift-downloads/drivers/jdbc/1.2.43.1067/Amazon+Redshift+JDBC+Driver+Install+Guide.pdf
132128
*/
133-
// this SHOuLD LAND UP IN THE ARGUMENT CLASS ...
134-
@Nonnull
135-
private static String requireNonNull(String val, String msg) throws MetadataDumperUsageException {
136-
if (val != null) return val;
137-
throw new MetadataDumperUsageException(msg);
138-
}
139-
140-
@Nonnull
141-
private String makeJdbcUrlPostgresql(ConnectorArguments arguments)
142-
throws MetadataDumperUsageException, UnsupportedEncodingException {
143-
String password = arguments.getPasswordIfFlagProvided().orElse(null);
144-
return "jdbc:postgresql://"
145-
+ arguments.getHostOrDefault()
146-
+ ":"
147-
+ arguments.getPort(5439)
148-
+ "/"
149-
+ Iterables.getFirst(arguments.getDatabases(), "") //
150-
+ new JdbcPropBuilder("?=&")
151-
.propOrWarn("user", arguments.getUser(), "--user must be specified")
152-
.propOrWarn("password", password, "--password must be specified")
153-
.prop("ssl", "true")
154-
.toJdbcPart();
155-
}
156-
157-
@Nonnull
158-
private String makeJdbcUrlRedshiftSimple(ConnectorArguments arguments)
159-
throws MetadataDumperUsageException, UnsupportedEncodingException {
160-
String password = arguments.getPasswordIfFlagProvided().orElse(null);
161-
return "jdbc:redshift://"
162-
+ arguments.getHostOrDefault()
163-
+ ":"
164-
+ arguments.getPort(5439)
165-
+ "/"
166-
+ Iterables.getFirst(arguments.getDatabases(), "") //
167-
+ new JdbcPropBuilder("?=&")
168-
.propOrWarn("UID", arguments.getUser(), "--user must be specified")
169-
.propOrWarn("PWD", password, "--password must be specified")
170-
.toJdbcPart();
171-
}
172-
173-
// TODO: [cluster-id]:[region] syntax.
174-
// either profile, or key+ secret
175-
@Nonnull
176-
private String makeJdbcUrlRedshiftIAM(ConnectorArguments arguments)
177-
throws MetadataDumperUsageException, UnsupportedEncodingException {
178-
String url =
179-
"jdbc:redshift:iam://"
180-
+ arguments.getHostOrDefault()
181-
+ ":"
182-
+ arguments.getPort(5439)
183-
+ "/"
184-
+ Iterables.getFirst(arguments.getDatabases(), "");
185-
186-
if (arguments.getIAMProfile() != null)
187-
url += new JdbcPropBuilder("?=&").prop("Profile", arguments.getIAMProfile()).toJdbcPart();
188-
else if (arguments.getIAMAccessKeyID() != null && arguments.getIAMSecretAccessKey() != null)
189-
url +=
190-
new JdbcPropBuilder("?=&")
191-
.prop("AccessKeyID", arguments.getIAMAccessKeyID())
192-
.prop("SecretAccessKey", arguments.getIAMSecretAccessKey())
193-
.propOrError("DbUser", arguments.getUser(), "--user must be specified")
194-
.toJdbcPart();
195-
// Will use the default IAM from ~/.aws/credentials/
196-
// throw new MetadataDumperUsageException("Either --iam-profile or
197-
// --iam-accesskeyid/--iam-secretaccesskey should be given");
198-
return url;
199-
}
200129

201130
@Override
202-
public Handle open(ConnectorArguments arguments) throws Exception {
131+
@Nonnull
132+
public Handle open(@Nonnull ConnectorArguments arguments) throws Exception {
203133

204134
Driver driver =
205135
newDriver(
206136
arguments.getDriverPaths(), "com.amazon.redshift.jdbc.Driver", "org.postgresql.Driver");
207137

208-
// LOG.debug("DRIVER IS " + driver.getClass().getCanonicalName());
209-
// LOG.debug("DRIVER CAN RS " + driver.acceptsURL("jdbc:redshift://host/db"));
210-
// LOG.debug("DRIVER CAN IAM " + driver.acceptsURL("jdbc:redshift:iam://host/db"));
211-
// LOG.debug("DRIVER CAN PG " + driver.acceptsURL("jdbc:postgresql://host/db"));
212138
String url = arguments.getUri();
213139
Optional<String> password = arguments.getPasswordIfFlagProvided();
214140
if (url == null) {
@@ -226,11 +152,11 @@ public Handle open(ConnectorArguments arguments) throws Exception {
226152
"The use of IAM authentication also requires the use of a Redshift-specific JDBC driver. Please use --"
227153
+ ConnectorArguments.OPT_DRIVER
228154
+ " to specify the path to the Redshift JDBC JAR, or use password authentication.");
229-
url = makeJdbcUrlPostgresql(arguments);
155+
url = RedshiftUrlUtil.makeJdbcUrlPostgresql(arguments);
230156
} else if (isAuthenticationPassword) {
231-
url = makeJdbcUrlRedshiftSimple(arguments);
157+
url = RedshiftUrlUtil.makeJdbcUrlRedshiftSimple(arguments);
232158
} else {
233-
url = makeJdbcUrlRedshiftIAM(arguments);
159+
url = RedshiftUrlUtil.makeJdbcUrlRedshiftIAM(arguments);
234160
}
235161
}
236162

@@ -243,4 +169,11 @@ public Handle open(ConnectorArguments arguments) throws Exception {
243169

244170
return JdbcHandle.newPooledJdbcHandle(dataSource, arguments.getThreadPoolSize());
245171
}
172+
173+
private static void logDriverInfo(@Nonnull Driver driver) throws SQLException {
174+
LOG.debug("DRIVER IS " + driver.getClass().getCanonicalName());
175+
LOG.debug("DRIVER CAN RS " + driver.acceptsURL("jdbc:redshift://host/db"));
176+
LOG.debug("DRIVER CAN IAM " + driver.acceptsURL("jdbc:redshift:iam://host/db"));
177+
LOG.debug("DRIVER CAN PG " + driver.acceptsURL("jdbc:postgresql://host/db"));
178+
}
246179
}

dumper/app/src/main/java/com/google/edwmigration/dumper/application/dumper/connector/redshift/RedshiftLogsConnector.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
arg = ConnectorArguments.OPT_PORT,
5656
description = "The port of the server.",
5757
required = ConnectorArguments.OPT_REQUIRED_IF_NOT_URL,
58-
defaultValue = "" + RedshiftMetadataConnector.OPT_PORT_DEFAULT)
58+
defaultValue = RedshiftUrlUtil.OPT_PORT_DEFAULT)
5959
@RespectsArgumentQueryLogDays
6060
@RespectsArgumentQueryLogStart
6161
@RespectsArgumentQueryLogEnd

dumper/app/src/main/java/com/google/edwmigration/dumper/application/dumper/connector/redshift/RedshiftMetadataConnector.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
arg = ConnectorArguments.OPT_PORT,
4242
description = "The port of the server.",
4343
required = ConnectorArguments.OPT_REQUIRED_IF_NOT_URL,
44-
defaultValue = "" + RedshiftMetadataConnector.OPT_PORT_DEFAULT)
44+
defaultValue = RedshiftUrlUtil.OPT_PORT_DEFAULT)
4545
public class RedshiftMetadataConnector extends AbstractRedshiftConnector
4646
implements MetadataConnector, RedshiftMetadataDumpFormat {
4747

dumper/app/src/main/java/com/google/edwmigration/dumper/application/dumper/connector/redshift/RedshiftRawLogsConnector.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
arg = ConnectorArguments.OPT_PORT,
6464
description = "The port of the server.",
6565
required = ConnectorArguments.OPT_REQUIRED_IF_NOT_URL,
66-
defaultValue = "" + RedshiftMetadataConnector.OPT_PORT_DEFAULT)
66+
defaultValue = RedshiftUrlUtil.OPT_PORT_DEFAULT)
6767
@RespectsArgumentAssessment
6868
@RespectsArgumentQueryLogDays
6969
@RespectsArgumentQueryLogStart
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/*
2+
* Copyright 2022-2024 Google LLC
3+
* Copyright 2013-2021 CompilerWorks
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package com.google.edwmigration.dumper.application.dumper.connector.redshift;
18+
19+
import com.google.common.collect.Iterables;
20+
import com.google.edwmigration.dumper.application.dumper.ConnectorArguments;
21+
import com.google.edwmigration.dumper.application.dumper.MetadataDumperUsageException;
22+
import java.io.UnsupportedEncodingException;
23+
import javax.annotation.Nonnull;
24+
import javax.annotation.ParametersAreNonnullByDefault;
25+
26+
@ParametersAreNonnullByDefault
27+
class RedshiftUrlUtil {
28+
29+
private static final int DEFAULT_PORT = 5439;
30+
// for annotations
31+
static final String OPT_PORT_DEFAULT = "5439";
32+
33+
@Nonnull
34+
static String makeJdbcUrlPostgresql(ConnectorArguments arguments)
35+
throws MetadataDumperUsageException, UnsupportedEncodingException {
36+
String password = arguments.getPasswordIfFlagProvided().orElse(null);
37+
return makeScheme("postgresql")
38+
+ arguments.getHostOrDefault()
39+
+ ":"
40+
+ arguments.getPort(DEFAULT_PORT)
41+
+ "/"
42+
+ Iterables.getFirst(arguments.getDatabases(), "")
43+
+ new JdbcPropBuilder("?=&")
44+
.propOrWarn("user", arguments.getUser(), "--user must be specified")
45+
.propOrWarn("password", password, "--password must be specified")
46+
.prop("ssl", "true")
47+
.toJdbcPart();
48+
}
49+
50+
@Nonnull
51+
static String makeJdbcUrlRedshiftSimple(ConnectorArguments arguments)
52+
throws MetadataDumperUsageException, UnsupportedEncodingException {
53+
String password = arguments.getPasswordIfFlagProvided().orElse(null);
54+
return makeScheme("redshift")
55+
+ arguments.getHostOrDefault()
56+
+ ":"
57+
+ arguments.getPort(DEFAULT_PORT)
58+
+ "/"
59+
+ Iterables.getFirst(arguments.getDatabases(), "")
60+
+ new JdbcPropBuilder("?=&")
61+
.propOrWarn("UID", arguments.getUser(), "--user must be specified")
62+
.propOrWarn("PWD", password, "--password must be specified")
63+
.toJdbcPart();
64+
}
65+
66+
// TODO: [cluster-id]:[region] syntax.
67+
// either profile, or key+ secret
68+
@Nonnull
69+
static String makeJdbcUrlRedshiftIAM(ConnectorArguments arguments)
70+
throws UnsupportedEncodingException {
71+
return makeScheme("redshift:iam")
72+
+ arguments.getHostOrDefault()
73+
+ ":"
74+
+ arguments.getPort(DEFAULT_PORT)
75+
+ "/"
76+
+ Iterables.getFirst(arguments.getDatabases(), "")
77+
+ makeIamProperties(arguments);
78+
}
79+
80+
private static String makeScheme(String urlType) {
81+
return String.format("jdbc:%s://", urlType);
82+
}
83+
84+
private static String makeIamProperties(ConnectorArguments arguments)
85+
throws UnsupportedEncodingException {
86+
String profile = arguments.getIAMProfile();
87+
if (profile != null) {
88+
return new JdbcPropBuilder("?=&").prop("Profile", arguments.getIAMProfile()).toJdbcPart();
89+
}
90+
String keyId = arguments.getIAMAccessKeyID();
91+
String secretKey = arguments.getIAMSecretAccessKey();
92+
if (keyId != null && secretKey != null) {
93+
return new JdbcPropBuilder("?=&")
94+
.prop("AccessKeyID", keyId)
95+
.prop("SecretAccessKey", secretKey)
96+
.propOrError("DbUser", arguments.getUser(), "--user must be specified")
97+
.toJdbcPart();
98+
} else {
99+
// Use the default IAM from ~/.aws/credentials/
100+
return "";
101+
}
102+
}
103+
}

0 commit comments

Comments
 (0)