-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Reactive Datasource: support CredentialsProvider changing values
Instead of: - creating pgConnectOptions after calling the CredentialsProvider on startup - using static pool configuration We: - use dynamic pool configuration - call the Credentials provider every time a new connection must be created
- Loading branch information
1 parent
197c921
commit 3e5afbf
Showing
31 changed files
with
679 additions
and
69 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
38 changes: 38 additions & 0 deletions
38
...loyment/src/test/java/io/quarkus/reactive/datasource/ChangingCredentialsProviderBase.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,38 @@ | ||
package io.quarkus.reactive.datasource; | ||
|
||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
import org.jboss.logging.Logger; | ||
|
||
import io.quarkus.credentials.CredentialsProvider; | ||
|
||
public abstract class ChangingCredentialsProviderBase implements CredentialsProvider { | ||
|
||
private static final Logger log = Logger.getLogger(ChangingCredentialsProviderBase.class.getName()); | ||
|
||
private final String user2; | ||
private final String password2; | ||
|
||
private volatile Map<String, String> properties; | ||
|
||
protected ChangingCredentialsProviderBase(String user1, String password1, String user2, String password2) { | ||
properties = new HashMap<>(); | ||
properties.put(USER_PROPERTY_NAME, user1); | ||
properties.put(PASSWORD_PROPERTY_NAME, password1); | ||
this.user2 = user2; | ||
this.password2 = password2; | ||
} | ||
|
||
public void changeProperties() { | ||
properties = new HashMap<>(); | ||
properties.put(USER_PROPERTY_NAME, user2); | ||
properties.put(PASSWORD_PROPERTY_NAME, password2); | ||
} | ||
|
||
@Override | ||
public Map<String, String> getCredentials(String credentialsProviderName) { | ||
log.info("credentials provider returning " + properties); | ||
return properties; | ||
} | ||
} |
36 changes: 36 additions & 0 deletions
36
.../deployment/src/test/java/io/quarkus/reactive/datasource/ChangingCredentialsTestBase.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,36 @@ | ||
package io.quarkus.reactive.datasource; | ||
|
||
import static io.restassured.RestAssured.given; | ||
import static java.util.concurrent.TimeUnit.SECONDS; | ||
|
||
import org.hamcrest.CoreMatchers; | ||
import org.junit.jupiter.api.Test; | ||
|
||
public abstract class ChangingCredentialsTestBase { | ||
|
||
private String user1; | ||
private String user2; | ||
|
||
protected ChangingCredentialsTestBase(String user1, String user2) { | ||
this.user1 = user1; | ||
this.user2 = user2; | ||
} | ||
|
||
@Test | ||
public void testConnect() throws Exception { | ||
given() | ||
.when().get("/test") | ||
.then() | ||
.statusCode(200) | ||
.body(CoreMatchers.equalTo(user1)); | ||
|
||
SECONDS.sleep(2); // sleep longer than pool idle connection timeout | ||
|
||
given() | ||
.when().get("/test") | ||
.then() | ||
.statusCode(200) | ||
.body(CoreMatchers.equalTo(user2)); | ||
} | ||
|
||
} |
67 changes: 67 additions & 0 deletions
67
.../runtime/src/main/java/io/quarkus/reactive/datasource/runtime/ConnectOptionsSupplier.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,67 @@ | ||
package io.quarkus.reactive.datasource.runtime; | ||
|
||
import static io.quarkus.credentials.CredentialsProvider.PASSWORD_PROPERTY_NAME; | ||
import static io.quarkus.credentials.CredentialsProvider.USER_PROPERTY_NAME; | ||
|
||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.concurrent.atomic.AtomicInteger; | ||
import java.util.function.IntUnaryOperator; | ||
import java.util.function.Supplier; | ||
import java.util.function.UnaryOperator; | ||
|
||
import io.quarkus.credentials.CredentialsProvider; | ||
import io.vertx.core.Future; | ||
import io.vertx.core.Handler; | ||
import io.vertx.core.Promise; | ||
import io.vertx.core.Vertx; | ||
import io.vertx.sqlclient.SqlConnectOptions; | ||
|
||
public class ConnectOptionsSupplier<CO extends SqlConnectOptions> implements Supplier<Future<CO>> { | ||
|
||
private final Vertx vertx; | ||
private final CredentialsProvider credentialsProvider; | ||
private final String credentialsProviderName; | ||
private final List<CO> connectOptionsList; | ||
private final UnaryOperator<CO> connectOptionsCopy; | ||
private final Handler<Promise<CO>> blockingCodeHandler; | ||
|
||
public ConnectOptionsSupplier(Vertx vertx, CredentialsProvider credentialsProvider, String credentialsProviderName, | ||
List<CO> connectOptionsList, UnaryOperator<CO> connectOptionsCopy) { | ||
this.vertx = vertx; | ||
this.credentialsProvider = credentialsProvider; | ||
this.credentialsProviderName = credentialsProviderName; | ||
this.connectOptionsList = connectOptionsList; | ||
this.connectOptionsCopy = connectOptionsCopy; | ||
blockingCodeHandler = new BlockingCodeHandler(); | ||
} | ||
|
||
@Override | ||
public Future<CO> get() { | ||
return vertx.executeBlocking(blockingCodeHandler, false); | ||
} | ||
|
||
private class BlockingCodeHandler implements Handler<Promise<CO>>, IntUnaryOperator { | ||
|
||
final AtomicInteger idx = new AtomicInteger(); | ||
|
||
@Override | ||
public void handle(Promise<CO> promise) { | ||
Map<String, String> credentials = credentialsProvider.getCredentials(credentialsProviderName); | ||
String user = credentials.get(USER_PROPERTY_NAME); | ||
String password = credentials.get(PASSWORD_PROPERTY_NAME); | ||
|
||
int nextIdx = idx.getAndUpdate(this); | ||
|
||
CO connectOptions = connectOptionsCopy.apply(connectOptionsList.get(nextIdx)); | ||
connectOptions.setUser(user).setPassword(password); | ||
|
||
promise.complete(connectOptions); | ||
} | ||
|
||
@Override | ||
public int applyAsInt(int previousIdx) { | ||
return previousIdx == connectOptionsList.size() - 1 ? 0 : previousIdx + 1; | ||
} | ||
} | ||
} |
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
13 changes: 13 additions & 0 deletions
13
...eployment/src/test/java/io/quarkus/reactive/mssql/client/ChangingCredentialsProvider.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,13 @@ | ||
package io.quarkus.reactive.mssql.client; | ||
|
||
import jakarta.enterprise.context.ApplicationScoped; | ||
|
||
import io.quarkus.reactive.datasource.ChangingCredentialsProviderBase; | ||
|
||
@ApplicationScoped | ||
public class ChangingCredentialsProvider extends ChangingCredentialsProviderBase { | ||
|
||
public ChangingCredentialsProvider() { | ||
super("sa", "A_Str0ng_Required_Password", "user2", "user2_Has_A_Str0ng_Required_Password"); | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
...nt/deployment/src/test/java/io/quarkus/reactive/mssql/client/ChangingCredentialsTest.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,20 @@ | ||
package io.quarkus.reactive.mssql.client; | ||
|
||
import org.junit.jupiter.api.extension.RegisterExtension; | ||
|
||
import io.quarkus.reactive.datasource.ChangingCredentialsTestBase; | ||
import io.quarkus.test.QuarkusUnitTest; | ||
|
||
public class ChangingCredentialsTest extends ChangingCredentialsTestBase { | ||
|
||
@RegisterExtension | ||
static final QuarkusUnitTest config = new QuarkusUnitTest() | ||
.withApplicationRoot((jar) -> jar | ||
.addClass(ChangingCredentialsProvider.class) | ||
.addClass(ChangingCredentialsTestResource.class) | ||
.addAsResource("application-changing-credentials.properties", "application.properties")); | ||
|
||
public ChangingCredentialsTest() { | ||
super("dbo", "user2"); | ||
} | ||
} |
41 changes: 41 additions & 0 deletions
41
...yment/src/test/java/io/quarkus/reactive/mssql/client/ChangingCredentialsTestResource.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,41 @@ | ||
package io.quarkus.reactive.mssql.client; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
|
||
import jakarta.enterprise.event.Observes; | ||
import jakarta.inject.Inject; | ||
import jakarta.ws.rs.GET; | ||
import jakarta.ws.rs.Path; | ||
import jakarta.ws.rs.Produces; | ||
import jakarta.ws.rs.core.MediaType; | ||
import jakarta.ws.rs.core.Response; | ||
|
||
import io.quarkus.runtime.StartupEvent; | ||
import io.smallrye.mutiny.Uni; | ||
import io.vertx.mutiny.mssqlclient.MSSQLPool; | ||
|
||
@Path("/test") | ||
public class ChangingCredentialsTestResource { | ||
|
||
@Inject | ||
MSSQLPool client; | ||
|
||
@Inject | ||
ChangingCredentialsProvider credentialsProvider; | ||
|
||
void addUser(@Observes StartupEvent ignored) { | ||
client.query("CREATE LOGIN user2 WITH PASSWORD = 'user2_Has_A_Str0ng_Required_Password'").executeAndAwait(); | ||
client.query("CREATE USER user2 FOR LOGIN user2").executeAndAwait(); | ||
} | ||
|
||
@GET | ||
@Produces(MediaType.TEXT_PLAIN) | ||
public Uni<Response> connect() { | ||
return client.query("SELECT CURRENT_USER").execute() | ||
.map(rowSet -> { | ||
assertEquals(1, rowSet.size()); | ||
return Response.ok(rowSet.iterator().next().getString(0)).build(); | ||
}).eventually(credentialsProvider::changeProperties); | ||
} | ||
|
||
} |
Oops, something went wrong.