Skip to content

Commit e7ccd39

Browse files
authored
[core] Public RESTTokenFileIO.validToken which can be invoked by native engines to get the token (#5063)
1 parent 155e51c commit e7ccd39

File tree

2 files changed

+90
-48
lines changed

2 files changed

+90
-48
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
package org.apache.paimon.rest;
20+
21+
import javax.annotation.Nullable;
22+
23+
import java.io.Serializable;
24+
import java.util.Map;
25+
import java.util.Objects;
26+
27+
/** Token for REST Catalog to access file io. */
28+
public class RESTToken implements Serializable {
29+
30+
private static final long serialVersionUID = 1L;
31+
32+
private final Map<String, String> token;
33+
private final long expireAtMillis;
34+
35+
/** Cache the hash code. */
36+
@Nullable private Integer hash;
37+
38+
public RESTToken(Map<String, String> token, long expireAtMillis) {
39+
this.token = token;
40+
this.expireAtMillis = expireAtMillis;
41+
}
42+
43+
public Map<String, String> token() {
44+
return token;
45+
}
46+
47+
public long expireAtMillis() {
48+
return expireAtMillis;
49+
}
50+
51+
@Override
52+
public boolean equals(Object o) {
53+
if (o == null || getClass() != o.getClass()) {
54+
return false;
55+
}
56+
RESTToken token1 = (RESTToken) o;
57+
return expireAtMillis == token1.expireAtMillis && Objects.equals(token, token1.token);
58+
}
59+
60+
@Override
61+
public int hashCode() {
62+
if (hash == null) {
63+
hash = Objects.hash(token, expireAtMillis);
64+
}
65+
return hash;
66+
}
67+
}

paimon-core/src/main/java/org/apache/paimon/rest/RESTTokenFileIO.java

Lines changed: 23 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,8 @@
3434
import org.apache.paimon.shade.caffeine2.com.github.benmanes.caffeine.cache.Caffeine;
3535
import org.apache.paimon.shade.caffeine2.com.github.benmanes.caffeine.cache.Scheduler;
3636

37-
import javax.annotation.Nullable;
38-
3937
import java.io.IOException;
40-
import java.io.Serializable;
4138
import java.io.UncheckedIOException;
42-
import java.util.Map;
43-
import java.util.Objects;
4439
import java.util.concurrent.Executors;
4540
import java.util.concurrent.TimeUnit;
4641

@@ -51,7 +46,7 @@ public class RESTTokenFileIO implements FileIO {
5146

5247
private static final long serialVersionUID = 1L;
5348

54-
private static final Cache<Token, FileIO> FILE_IO_CACHE =
49+
private static final Cache<RESTToken, FileIO> FILE_IO_CACHE =
5550
Caffeine.newBuilder()
5651
.expireAfterAccess(30, TimeUnit.MINUTES)
5752
.maximumSize(100)
@@ -74,7 +69,7 @@ public class RESTTokenFileIO implements FileIO {
7469

7570
// the latest token from REST Server, serializable in order to avoid loading token from the REST
7671
// Server again after serialization
77-
private volatile Token token;
72+
private volatile RESTToken token;
7873

7974
public RESTTokenFileIO(
8075
RESTCatalogLoader catalogLoader,
@@ -142,13 +137,7 @@ public boolean isObjectStore() {
142137
}
143138

144139
private FileIO fileIO() throws IOException {
145-
if (shouldRefresh()) {
146-
synchronized (this) {
147-
if (shouldRefresh()) {
148-
refreshToken();
149-
}
150-
}
151-
}
140+
tryToRefreshToken();
152141

153142
FileIO fileIO = FILE_IO_CACHE.getIfPresent(token);
154143
if (fileIO != null) {
@@ -163,7 +152,7 @@ private FileIO fileIO() throws IOException {
163152

164153
CatalogContext context = catalogLoader.context();
165154
Options options = context.options();
166-
options = new Options(RESTUtil.merge(options.toMap(), token.token));
155+
options = new Options(RESTUtil.merge(options.toMap(), token.token()));
167156
options.set(FILE_IO_ALLOW_CACHE, false);
168157
context = CatalogContext.create(options, context.preferIO(), context.fallbackIO());
169158
try {
@@ -176,8 +165,18 @@ private FileIO fileIO() throws IOException {
176165
}
177166
}
178167

168+
private void tryToRefreshToken() {
169+
if (shouldRefresh()) {
170+
synchronized (this) {
171+
if (shouldRefresh()) {
172+
refreshToken();
173+
}
174+
}
175+
}
176+
}
177+
179178
private boolean shouldRefresh() {
180-
return token == null || System.currentTimeMillis() > token.expireAtMillis;
179+
return token == null || System.currentTimeMillis() > token.expireAtMillis();
181180
}
182181

183182
private void refreshToken() {
@@ -192,39 +191,15 @@ private void refreshToken() {
192191
}
193192
}
194193

195-
token = new Token(response.getToken(), response.getExpiresAtMillis());
194+
token = new RESTToken(response.getToken(), response.getExpiresAtMillis());
196195
}
197196

198-
private static class Token implements Serializable {
199-
200-
private static final long serialVersionUID = 1L;
201-
202-
private final Map<String, String> token;
203-
private final long expireAtMillis;
204-
205-
/** Cache the hash code. */
206-
@Nullable private Integer hash;
207-
208-
private Token(Map<String, String> token, long expireAtMillis) {
209-
this.token = token;
210-
this.expireAtMillis = expireAtMillis;
211-
}
212-
213-
@Override
214-
public boolean equals(Object o) {
215-
if (o == null || getClass() != o.getClass()) {
216-
return false;
217-
}
218-
Token token1 = (Token) o;
219-
return expireAtMillis == token1.expireAtMillis && Objects.equals(token, token1.token);
220-
}
221-
222-
@Override
223-
public int hashCode() {
224-
if (hash == null) {
225-
hash = Objects.hash(token, expireAtMillis);
226-
}
227-
return hash;
228-
}
197+
/**
198+
* Public interface to get valid token, this can be invoked by native engines to get the token
199+
* and use own File System.
200+
*/
201+
public RESTToken validToken() {
202+
tryToRefreshToken();
203+
return token;
229204
}
230205
}

0 commit comments

Comments
 (0)