Skip to content

Commit 4682564

Browse files
chenjian2664wendigolosipiuk
committed
Add gcs.auth-type configuration
This makes it easier to add new GCS authentication types in the future. The commit also deprecate `gcs.use-access-token` Co-Authored-By: Mateusz "Serafin" Gajewski <[email protected]> Co-Authored-By: Łukasz Osipiuk <[email protected]>
1 parent 99b40f8 commit 4682564

File tree

4 files changed

+131
-19
lines changed

4 files changed

+131
-19
lines changed

docs/src/main/sphinx/object-storage/file-system-gcs.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,15 @@ Cloud Storage:
7070
- Description
7171
* - `gcs.use-access-token`
7272
- Flag to set usage of a client-provided OAuth 2.0 token to access Google
73-
Cloud Storage. Defaults to `false`.
73+
Cloud Storage. Defaults to `false`, deprecated to use `gcs.auth-type` instead.
74+
* - `gcs.auth-type`
75+
- Authentication type to use for Google Cloud Storage access. Default to `DEFAULT`.
76+
Supported values are:
77+
* `DEFAULT`: loads credentials from the environment. Either `gcs.json-key` or
78+
`gcs.json-key-file-path` can be set in addition to override the default
79+
credentials provider.
80+
* `ACCESS_TOKEN`: usage of client-provided OAuth 2.0 token to access Google
81+
Cloud Storage.
7482
* - `gcs.json-key`
7583
- Your Google Cloud service account key in JSON format. Not to be set together
7684
with `gcs.json-key-file-path`.
@@ -103,7 +111,7 @@ Cloud Storage, make the following edits to your catalog configuration:
103111
- Native property
104112
- Notes
105113
* - `hive.gcs.use-access-token`
106-
- `gcs.use-access-token`
114+
- `gcs.auth-type`
107115
-
108116
* - `hive.gcs.json-key-file-path`
109117
- `gcs.json-key-file-path`

lib/trino-filesystem-gcs/src/main/java/io/trino/filesystem/gcs/GcsFileSystemConfig.java

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@
3333

3434
public class GcsFileSystemConfig
3535
{
36+
public enum AuthType
37+
{
38+
ACCESS_TOKEN,
39+
DEFAULT;
40+
}
41+
3642
private DataSize readBlockSize = DataSize.of(2, MEGABYTE);
3743
private DataSize writeBlockSize = DataSize.of(16, MEGABYTE);
3844
private int pageSize = 100;
@@ -41,7 +47,8 @@ public class GcsFileSystemConfig
4147
private String projectId;
4248
private Optional<String> endpoint = Optional.empty();
4349

44-
private boolean useGcsAccessToken;
50+
private Optional<Boolean> useGcsAccessToken = Optional.empty();
51+
private Optional<AuthType> authType = Optional.empty();
4552
private String jsonKey;
4653
private String jsonKeyFilePath;
4754
private int maxRetries = 20;
@@ -134,15 +141,33 @@ public GcsFileSystemConfig setEndpoint(Optional<String> endpoint)
134141
return this;
135142
}
136143

144+
@NotNull
145+
public AuthType getAuthType()
146+
{
147+
if (useGcsAccessToken.isPresent() && useGcsAccessToken.get()) {
148+
return AuthType.ACCESS_TOKEN;
149+
}
150+
return authType.orElse(AuthType.DEFAULT);
151+
}
152+
153+
@Config("gcs.auth-type")
154+
public GcsFileSystemConfig setAuthType(AuthType authType)
155+
{
156+
this.authType = Optional.of(authType);
157+
return this;
158+
}
159+
160+
@Deprecated
137161
public boolean isUseGcsAccessToken()
138162
{
139-
return useGcsAccessToken;
163+
return useGcsAccessToken.orElse(false);
140164
}
141165

166+
@Deprecated
142167
@Config("gcs.use-access-token")
143168
public GcsFileSystemConfig setUseGcsAccessToken(boolean useGcsAccessToken)
144169
{
145-
this.useGcsAccessToken = useGcsAccessToken;
170+
this.useGcsAccessToken = Optional.of(useGcsAccessToken);
146171
return this;
147172
}
148173

@@ -268,13 +293,19 @@ public boolean isRetryDelayValid()
268293
return minBackoffDelay.compareTo(maxBackoffDelay) <= 0;
269294
}
270295

271-
@AssertTrue(message = "Either gcs.use-access-token or gcs.json-key or gcs.json-key-file-path must be set")
296+
@AssertTrue(message = "Either gcs.auth-type or gcs.json-key or gcs.json-key-file-path must be set")
272297
public boolean isAuthMethodValid()
273298
{
274-
if (useGcsAccessToken) {
299+
if (getAuthType() == AuthType.ACCESS_TOKEN) {
275300
return jsonKey == null && jsonKeyFilePath == null;
276301
}
277302

278303
return (jsonKey == null) ^ (jsonKeyFilePath == null);
279304
}
305+
306+
@AssertTrue(message = "Cannot set both gcs.use-access-token and gcs.auth-type")
307+
public boolean isAuthTypeAndUseGcsAccessTokenMutuallyExclusive()
308+
{
309+
return !(authType.isPresent() && useGcsAccessToken.isPresent());
310+
}
280311
}

lib/trino-filesystem-gcs/src/main/java/io/trino/filesystem/gcs/GcsFileSystemModule.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
import com.google.inject.Scopes;
1818
import io.airlift.configuration.AbstractConfigurationAwareModule;
1919

20-
import static io.airlift.configuration.ConditionalModule.conditionalModule;
2120
import static io.airlift.configuration.ConfigBinder.configBinder;
21+
import static io.airlift.configuration.SwitchModule.switchModule;
2222

2323
public class GcsFileSystemModule
2424
extends AbstractConfigurationAwareModule
@@ -30,10 +30,12 @@ protected void setup(Binder binder)
3030
binder.bind(GcsStorageFactory.class).in(Scopes.SINGLETON);
3131
binder.bind(GcsFileSystemFactory.class).in(Scopes.SINGLETON);
3232

33-
install(conditionalModule(
33+
install(switchModule(
3434
GcsFileSystemConfig.class,
35-
GcsFileSystemConfig::isUseGcsAccessToken,
36-
_ -> binder.bind(GcsAuth.class).to(GcsAccessTokenAuth.class).in(Scopes.SINGLETON),
37-
_ -> binder.bind(GcsAuth.class).to(GcsDefaultAuth.class).in(Scopes.SINGLETON)));
35+
GcsFileSystemConfig::getAuthType,
36+
type -> switch (type) {
37+
case ACCESS_TOKEN -> _ -> binder.bind(GcsAuth.class).to(GcsAccessTokenAuth.class).in(Scopes.SINGLETON);
38+
case DEFAULT -> _ -> binder.bind(GcsAuth.class).to(GcsDefaultAuth.class).in(Scopes.SINGLETON);
39+
}));
3840
}
3941
}

lib/trino-filesystem-gcs/src/test/java/io/trino/filesystem/gcs/TestGcsFileSystemConfig.java

Lines changed: 78 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import com.google.common.collect.ImmutableMap;
1717
import io.airlift.units.DataSize;
1818
import io.airlift.units.Duration;
19+
import io.trino.filesystem.gcs.GcsFileSystemConfig.AuthType;
1920
import jakarta.validation.constraints.AssertTrue;
2021
import org.junit.jupiter.api.Test;
2122

@@ -41,9 +42,10 @@ void testDefaults()
4142
.setWriteBlockSize(DataSize.of(16, MEGABYTE))
4243
.setPageSize(100)
4344
.setBatchSize(100)
45+
.setUseGcsAccessToken(false)
4446
.setProjectId(null)
4547
.setEndpoint(Optional.empty())
46-
.setUseGcsAccessToken(false)
48+
.setAuthType(AuthType.DEFAULT)
4749
.setJsonKey(null)
4850
.setJsonKeyFilePath(null)
4951
.setMaxRetries(20)
@@ -56,6 +58,43 @@ void testDefaults()
5658

5759
@Test
5860
void testExplicitPropertyMappings()
61+
{
62+
Map<String, String> properties = ImmutableMap.<String, String>builder()
63+
.put("gcs.read-block-size", "51MB")
64+
.put("gcs.write-block-size", "52MB")
65+
.put("gcs.page-size", "10")
66+
.put("gcs.batch-size", "11")
67+
.put("gcs.project-id", "project")
68+
.put("gcs.endpoint", "http://custom.dns.org:8000")
69+
.put("gcs.auth-type", "access_token")
70+
.put("gcs.client.max-retries", "10")
71+
.put("gcs.client.backoff-scale-factor", "4.0")
72+
.put("gcs.client.max-retry-time", "10s")
73+
.put("gcs.client.min-backoff-delay", "20ms")
74+
.put("gcs.client.max-backoff-delay", "20ms")
75+
.put("gcs.application-id", "application id")
76+
.buildOrThrow();
77+
78+
GcsFileSystemConfig expected = new GcsFileSystemConfig()
79+
.setReadBlockSize(DataSize.of(51, MEGABYTE))
80+
.setWriteBlockSize(DataSize.of(52, MEGABYTE))
81+
.setPageSize(10)
82+
.setBatchSize(11)
83+
.setProjectId("project")
84+
.setEndpoint(Optional.of("http://custom.dns.org:8000"))
85+
.setAuthType(AuthType.ACCESS_TOKEN)
86+
.setMaxRetries(10)
87+
.setBackoffScaleFactor(4.0)
88+
.setMaxRetryTime(new Duration(10, SECONDS))
89+
.setMinBackoffDelay(new Duration(20, MILLISECONDS))
90+
.setMaxBackoffDelay(new Duration(20, MILLISECONDS))
91+
.setApplicationId("application id");
92+
assertFullMapping(properties, expected, Set.of("gcs.json-key", "gcs.json-key-file-path", "gcs.use-access-token"));
93+
}
94+
95+
// backwards compatibility test, remove if use-access-token is removed
96+
@Test
97+
void testExplicitPropertyMappingsWithDeprecatedUseAccessToken()
5998
{
6099
Map<String, String> properties = ImmutableMap.<String, String>builder()
61100
.put("gcs.read-block-size", "51MB")
@@ -87,34 +126,34 @@ void testExplicitPropertyMappings()
87126
.setMinBackoffDelay(new Duration(20, MILLISECONDS))
88127
.setMaxBackoffDelay(new Duration(20, MILLISECONDS))
89128
.setApplicationId("application id");
90-
assertFullMapping(properties, expected, Set.of("gcs.json-key", "gcs.json-key-file-path"));
129+
assertFullMapping(properties, expected, Set.of("gcs.json-key", "gcs.json-key-file-path", "gcs.auth-type"));
91130
}
92131

93132
@Test
94133
public void testValidation()
95134
{
96135
assertFailsValidation(
97136
new GcsFileSystemConfig()
98-
.setUseGcsAccessToken(true)
137+
.setAuthType(AuthType.ACCESS_TOKEN)
99138
.setJsonKey("{}}"),
100139
"authMethodValid",
101-
"Either gcs.use-access-token or gcs.json-key or gcs.json-key-file-path must be set",
140+
"Either gcs.auth-type or gcs.json-key or gcs.json-key-file-path must be set",
102141
AssertTrue.class);
103142

104143
assertFailsValidation(
105144
new GcsFileSystemConfig()
106-
.setUseGcsAccessToken(true)
145+
.setAuthType(AuthType.ACCESS_TOKEN)
107146
.setJsonKeyFilePath("/dev/null"),
108147
"authMethodValid",
109-
"Either gcs.use-access-token or gcs.json-key or gcs.json-key-file-path must be set",
148+
"Either gcs.auth-type or gcs.json-key or gcs.json-key-file-path must be set",
110149
AssertTrue.class);
111150

112151
assertFailsValidation(
113152
new GcsFileSystemConfig()
114153
.setJsonKey("{}")
115154
.setJsonKeyFilePath("/dev/null"),
116155
"authMethodValid",
117-
"Either gcs.use-access-token or gcs.json-key or gcs.json-key-file-path must be set",
156+
"Either gcs.auth-type or gcs.json-key or gcs.json-key-file-path must be set",
118157
AssertTrue.class);
119158

120159
assertFailsValidation(
@@ -125,5 +164,37 @@ public void testValidation()
125164
"retryDelayValid",
126165
"gcs.client.min-backoff-delay must be less than or equal to gcs.client.max-backoff-delay",
127166
AssertTrue.class);
167+
168+
assertFailsValidation(
169+
new GcsFileSystemConfig()
170+
.setAuthType(AuthType.ACCESS_TOKEN)
171+
.setUseGcsAccessToken(true),
172+
"authTypeAndUseGcsAccessTokenMutuallyExclusive",
173+
"Cannot set both gcs.use-access-token and gcs.auth-type",
174+
AssertTrue.class);
175+
176+
assertFailsValidation(
177+
new GcsFileSystemConfig()
178+
.setAuthType(AuthType.ACCESS_TOKEN)
179+
.setUseGcsAccessToken(false),
180+
"authTypeAndUseGcsAccessTokenMutuallyExclusive",
181+
"Cannot set both gcs.use-access-token and gcs.auth-type",
182+
AssertTrue.class);
183+
184+
assertFailsValidation(
185+
new GcsFileSystemConfig()
186+
.setUseGcsAccessToken(true)
187+
.setAuthType(AuthType.DEFAULT),
188+
"authTypeAndUseGcsAccessTokenMutuallyExclusive",
189+
"Cannot set both gcs.use-access-token and gcs.auth-type",
190+
AssertTrue.class);
191+
192+
assertFailsValidation(
193+
new GcsFileSystemConfig()
194+
.setUseGcsAccessToken(false)
195+
.setAuthType(AuthType.DEFAULT),
196+
"authTypeAndUseGcsAccessTokenMutuallyExclusive",
197+
"Cannot set both gcs.use-access-token and gcs.auth-type",
198+
AssertTrue.class);
128199
}
129200
}

0 commit comments

Comments
 (0)