-
Notifications
You must be signed in to change notification settings - Fork 3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add cached token option to jdbc externalAuthentication
This change allows sharing external authentication tokens between different Connections. Each time when a new token is required, first Connection that needs it, will handle obtaining a new token when all the other Connections wait for this operation to finish. Token is kept in memmory, guarded by ReadWriteLock. To enable token cache use externalAuthenticationTokenCache=MEMORY Default value for externalAuthenticationTokenCache is NONE.
- Loading branch information
Showing
12 changed files
with
475 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
34 changes: 34 additions & 0 deletions
34
client/trino-client/src/main/java/io/trino/client/auth/external/KnownToken.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License 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 io.trino.client.auth.external; | ||
|
||
import java.util.Optional; | ||
import java.util.function.Supplier; | ||
|
||
public interface KnownToken | ||
{ | ||
Optional<Token> getToken(); | ||
|
||
void setupToken(Supplier<Optional<Token>> tokenSource); | ||
|
||
static KnownToken local() | ||
{ | ||
return new LocalKnownToken(); | ||
} | ||
|
||
static KnownToken memoryCached() | ||
{ | ||
return MemoryCachedKnownToken.INSTANCE; | ||
} | ||
} |
46 changes: 46 additions & 0 deletions
46
client/trino-client/src/main/java/io/trino/client/auth/external/LocalKnownToken.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
/* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License 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 io.trino.client.auth.external; | ||
|
||
import javax.annotation.concurrent.NotThreadSafe; | ||
|
||
import java.util.Optional; | ||
import java.util.function.Supplier; | ||
|
||
import static java.util.Objects.requireNonNull; | ||
|
||
/** | ||
* LocalKnownToken class keeps the token on its field | ||
* and it's designed to use it in fully serialized manner. | ||
*/ | ||
@NotThreadSafe | ||
class LocalKnownToken | ||
implements KnownToken | ||
{ | ||
private Optional<Token> knownToken = Optional.empty(); | ||
|
||
@Override | ||
public Optional<Token> getToken() | ||
{ | ||
return knownToken; | ||
} | ||
|
||
@Override | ||
public void setupToken(Supplier<Optional<Token>> tokenSource) | ||
{ | ||
requireNonNull(tokenSource, "tokenSource is null"); | ||
|
||
knownToken = tokenSource.get(); | ||
} | ||
} |
83 changes: 83 additions & 0 deletions
83
client/trino-client/src/main/java/io/trino/client/auth/external/MemoryCachedKnownToken.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
/* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License 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 io.trino.client.auth.external; | ||
|
||
import javax.annotation.concurrent.ThreadSafe; | ||
|
||
import java.util.Optional; | ||
import java.util.concurrent.locks.Lock; | ||
import java.util.concurrent.locks.ReadWriteLock; | ||
import java.util.concurrent.locks.ReentrantReadWriteLock; | ||
import java.util.function.Supplier; | ||
|
||
/** | ||
* This KnownToken instance forces all Connections to reuse same token. | ||
* Every time an existing token is considered to be invalid each Connection | ||
* will try to obtain a new token, but only the first one will actually do the job, | ||
* where every other connection will be waiting on readLock | ||
* until obtaining new token finishes. | ||
* <p> | ||
* In general the game is to reuse same token and obtain it only once, no matter how | ||
* many Connections will be actively using it. It's very important as obtaining the new token | ||
* will take minutes, as it mostly requires user thinking time. | ||
*/ | ||
@ThreadSafe | ||
class MemoryCachedKnownToken | ||
implements KnownToken | ||
{ | ||
public static final MemoryCachedKnownToken INSTANCE = new MemoryCachedKnownToken(); | ||
|
||
private final ReadWriteLock lock = new ReentrantReadWriteLock(); | ||
private final Lock readLock = lock.readLock(); | ||
private final Lock writeLock = lock.writeLock(); | ||
private Optional<Token> knownToken = Optional.empty(); | ||
|
||
private MemoryCachedKnownToken() | ||
{ | ||
} | ||
|
||
@Override | ||
public Optional<Token> getToken() | ||
{ | ||
try { | ||
readLock.lockInterruptibly(); | ||
return knownToken; | ||
} | ||
catch (InterruptedException e) { | ||
Thread.currentThread().interrupt(); | ||
throw new RuntimeException(e); | ||
} | ||
finally { | ||
readLock.unlock(); | ||
} | ||
} | ||
|
||
@Override | ||
public void setupToken(Supplier<Optional<Token>> tokenSource) | ||
{ | ||
// Try to lock and generate new token. If some other thread (Connection) has | ||
// already obtained writeLock and is generating new token, then skipp this | ||
// to block on getToken() | ||
if (writeLock.tryLock()) { | ||
try { | ||
// Clear knownToken before obtaining new token, as it might fail leaving old invalid token. | ||
knownToken = Optional.empty(); | ||
knownToken = tokenSource.get(); | ||
} | ||
finally { | ||
writeLock.unlock(); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.