Skip to content

Commit

Permalink
Merge pull request #18090 from gsmet/2.0.0.final-backports-6
Browse files Browse the repository at this point in the history
2.0.0.Final backports 6
  • Loading branch information
gsmet authored Jun 23, 2021
2 parents 57530d2 + 78a9136 commit 8cdda6b
Show file tree
Hide file tree
Showing 10 changed files with 150 additions and 24 deletions.
2 changes: 1 addition & 1 deletion bom/application/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@
<commons-lang3.version>3.12.0</commons-lang3.version>
<commons-codec.version>1.15</commons-codec.version>
<classmate.version>1.5.1</classmate.version>
<hibernate-orm.version>5.5.2.Final</hibernate-orm.version>
<hibernate-orm.version>5.5.3.Final</hibernate-orm.version>
<hibernate-reactive.version>1.0.0.CR7</hibernate-reactive.version>
<hibernate-validator.version>6.2.0.Final</hibernate-validator.version>
<hibernate-search.version>6.0.4.Final</hibernate-search.version>
Expand Down
10 changes: 7 additions & 3 deletions docs/src/main/asciidoc/reactive-sql-clients.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,8 @@ The Reactive PostgreSQL Client can also prepare queries and take parameters that
client.preparedQuery("SELECT id, name FROM fruits WHERE id = $1").execute(Tuple.of(id))
----

TIP: The SQL string can refer to parameters by position, using $1, $2, ...etc.
TIP: For PostgreSQL, the SQL string can refer to parameters by position, using `$1`, `$2`, ...etc.
Please refer to the <<Database Clients details>> section for other databases.

Similar to the simple `query` method, `preparedQuery` returns an instance of `PreparedQuery<RowSet<Row>>`.
Equipped with this tooling, we are able to safely use an `id` provided by the user to get the details of a particular fruit:
Expand Down Expand Up @@ -467,21 +468,24 @@ Navigate to http://localhost:8080/fruits.html and read/create/delete some fruits

== Database Clients details

[cols="15,35,50"]
[cols="10,40,40,10"]
|===
|Database |Extension name |Pool class name
|Database |Extension name |Pool class name |Placeholders

|DB2
|`quarkus-reactive-db2-client`
|`io.vertx.mutiny.db2client.DB2Pool`
|`?`

|MariaDB/MySQL
|`quarkus-reactive-mysql-client`
|`io.vertx.mutiny.mysqlclient.MySQLPool`
|`?`

|PostgreSQL
|`quarkus-reactive-pg-client`
|`io.vertx.mutiny.pgclient.PgPool`
|`$1`, `$2`, etc.
|===

== Transactions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,28 @@ public RunningDevServicesDatasource startDatabase(Optional<String> username, Opt
new Closeable() {
@Override
public void close() throws IOException {
//make sure the DB is removed on close
try (Connection connection = DriverManager.getConnection(connectionUrl, "sa", "sa")) {
try (Statement statement = connection.createStatement()) {
statement.execute("SET DB_CLOSE_DELAY 0");
//Test first, to not make too much noise if the Server is dead already
//(perhaps we failed to start?)
if (tcpServer.isRunning(false)) {
//make sure the DB is removed on close
try (Connection connection = DriverManager.getConnection(
connectionUrl,
"sa",
"sa")) {
try (Statement statement = connection.createStatement()) {
statement.execute("SET DB_CLOSE_DELAY 0");
}
} catch (SQLException t) {
t.printStackTrace();
}
} catch (SQLException t) {
t.printStackTrace();
tcpServer.stop();
System.out.println(
"[INFO] H2 database was shut down; server status: " + tcpServer.getStatus());
} else {
System.out.println(
"[INFO] H2 database was NOT shut down as it appears it was down already; server status: "
+ tcpServer.getStatus());
}
tcpServer.stop();
System.out.println(
"[INFO] H2 database was shut down; server status: " + tcpServer.getStatus());
}
});
} catch (SQLException throwables) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<form method="post" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="datasource" value="{container.dataSourceName}">
<input type="hidden" name="operation" value="clean">
<input id="clear" type="submit" class="btn btn-primary btn-sm" value="Clean" >
<input id="clear" type="submit" class="btn btn-primary btn-sm" value="Clean" onclick="return confirm('This will drop all objects (tables, views, procedures, triggers, ...) in the configured schema. Do you want to continue?')" >
</form>
&nbsp;
<form method="post" enctype="application/x-www-form-urlencoded">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,9 @@ private static void injectRuntimeConfiguration(String persistenceUnitName,
runtimeSettingsBuilder.put(AvailableSettings.HBM2DDL_HALT_ON_ERROR, "true");
}

//Never append on existing scripts:
runtimeSettingsBuilder.put(AvailableSettings.HBM2DDL_SCRIPTS_CREATE_APPEND, "false");

runtimeSettingsBuilder.put(AvailableSettings.HBM2DDL_SCRIPTS_ACTION,
persistenceUnitConfig.scripts.generation.generation);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public static class HibernateOrmConfigPersistenceUnitDatabaseGeneration {
*
* `drop-and-create` is awesome in development mode.
*
* Accepted values: `none`, `create`, `drop-and-create`, `drop`, `update`.
* Accepted values: `none`, `create`, `drop-and-create`, `drop`, `update`, `validate`.
*/
@ConfigItem(name = ConfigItem.PARENT, defaultValue = "none")
public String generation = "none";
Expand Down Expand Up @@ -102,7 +102,7 @@ public static class HibernateOrmConfigPersistenceUnitScriptGeneration {
/**
* Select whether the database schema DDL files are generated or not.
*
* Accepted values: `none`, `create`, `drop-and-create`, `drop`, `update`.
* Accepted values: `none`, `create`, `drop-and-create`, `drop`, `update`, `validate`.
*/
@ConfigItem(name = ConfigItem.PARENT, defaultValue = "none")
public String generation = "none";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<form method="post" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="datasource" value="{liquibaseFactory.dataSourceName}">
<input type="hidden" name="operation" value="clean">
<input id="clear" type="submit" class="btn btn-primary btn-sm" value="Clean" >
<input id="clear" type="submit" class="btn btn-primary btn-sm" value="Clean" onclick="return confirm('This will drop all objects (tables, views, procedures, triggers, ...) in the configured schema. Do you want to continue?')" >
</form>
&nbsp;
<form method="post" enctype="application/x-www-form-urlencoded">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public String getLatestVersionFromRange(Artifact artifact, String versionRange)
*/
protected static ArtifactResult resolveAndCleanupOldTimestampedVersions(MavenArtifactResolver resolver, Artifact artifact,
boolean cleanupOldTimestampedVersions) throws BootstrapMavenException {
if (!cleanupOldTimestampedVersions) {
if (!artifact.isSnapshot() || !cleanupOldTimestampedVersions) {
return resolver.resolve(artifact);
}

Expand All @@ -63,7 +63,9 @@ protected static ArtifactResult resolveAndCleanupOldTimestampedVersions(MavenArt
if (jsonDirContent != null && jsonDirContent.length > existingFiles.size()) {
final String fileName = result.getArtifact().getFile().getName();
for (File c : jsonDirContent) {
if (c.getName().length() > fileName.length() && c.getName().startsWith(artifact.getArtifactId())
if (c.getName().length() > fileName.length()
&& c.getName().startsWith(artifact.getArtifactId())
&& c.getName().endsWith(artifact.getClassifier())
&& existingFiles.contains(c.getName())) {
c.deleteOnExit();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,16 @@
import java.util.List;
import java.util.Objects;
import java.util.Set;
import org.eclipse.aether.DefaultRepositorySystemSession;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.repository.RemoteRepository;
import org.eclipse.aether.repository.RepositoryPolicy;
import org.eclipse.aether.resolution.ArtifactResult;
import org.eclipse.aether.transfer.TransferCancelledException;
import org.eclipse.aether.transfer.TransferEvent;
import org.eclipse.aether.transfer.TransferListener;

public class MavenRegistryClientFactory implements RegistryClientFactory {

Expand Down Expand Up @@ -70,7 +75,9 @@ public RegistryClient buildRegistryClient(RegistryConfig config) throws Registry
Collections.emptyList(), singleRegistryRepos, true);
aggregatedRepos = resolver.getRemoteRepositoryManager().aggregateRepositories(resolver.getSession(),
aggregatedRepos, resolver.getRepositories(), false);
resolver = newResolver(resolver, aggregatedRepos);
resolver = newResolver(resolver, aggregatedRepos, config, log);
} else {
resolver = newResolver(resolver, resolver.getRepositories(), config, log);
}

final boolean cleanupTimestampedArtifacts = isCleanupTimestampedArtifacts(config);
Expand Down Expand Up @@ -326,12 +333,13 @@ private static boolean isComplete(RegistryMavenRepoConfig config) {
return true;
}

private static MavenArtifactResolver newResolver(MavenArtifactResolver resolver, List<RemoteRepository> aggregatedRepos) {
private static MavenArtifactResolver newResolver(MavenArtifactResolver resolver, List<RemoteRepository> aggregatedRepos,
RegistryConfig config, MessageWriter log) {
try {
final BootstrapMavenContext mvnCtx = new BootstrapMavenContext(
BootstrapMavenContext.config()
.setRepositorySystem(resolver.getSystem())
.setRepositorySystemSession(resolver.getSession())
.setRepositorySystemSession(setRegistryTransferListener(config, log, resolver.getSession()))
.setRemoteRepositoryManager(resolver.getRemoteRepositoryManager())
.setRemoteRepositories(aggregatedRepos)
.setLocalRepository(resolver.getMavenContext().getLocalRepo())
Expand All @@ -342,6 +350,63 @@ private static MavenArtifactResolver newResolver(MavenArtifactResolver resolver,
}
}

private static DefaultRepositorySystemSession setRegistryTransferListener(RegistryConfig config, MessageWriter log,
RepositorySystemSession session) {
final DefaultRepositorySystemSession newSession = new DefaultRepositorySystemSession(session);
final TransferListener tl = newSession.getTransferListener();
newSession.setTransferListener(new TransferListener() {

boolean refreshingLocalCache;

@Override
public void transferInitiated(TransferEvent event) throws TransferCancelledException {
if (!refreshingLocalCache) {
refreshingLocalCache = true;
log.info("Refreshing the local extension catalog cache of " + config.getId());
}
if (tl != null) {
tl.transferInitiated(event);
}
}

@Override
public void transferStarted(TransferEvent event) throws TransferCancelledException {
if (tl != null) {
tl.transferStarted(event);
}
}

@Override
public void transferProgressed(TransferEvent event) throws TransferCancelledException {
if (tl != null) {
tl.transferProgressed(event);
}
}

@Override
public void transferCorrupted(TransferEvent event) throws TransferCancelledException {
if (tl != null) {
tl.transferCorrupted(event);
}
}

@Override
public void transferSucceeded(TransferEvent event) {
if (tl != null) {
tl.transferSucceeded(event);
}
}

@Override
public void transferFailed(TransferEvent event) {
if (tl != null) {
tl.transferFailed(event);
}
}
});
return newSession;
}

private void determineExtraRepos(RegistryConfig config,
List<RemoteRepository> configuredRepos) {
final RegistryMavenConfig mavenConfig = config.getMaven() == null ? null : config.getMaven();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,8 +232,22 @@ static Properties readQuarkusArtifactProperties(ExtensionContext context) {
Path buildOutputDirectory = determineBuildOutputDirectory(context);
Path artifactProperties = buildOutputDirectory.resolve("quarkus-artifact.properties");
if (!Files.exists(artifactProperties)) {
throw new IllegalStateException(
"Unable to locate the artifact metadata file created that must be created by Quarkus in order to run integration tests.");
TestLauncher testLauncher = determineTestLauncher();
String errorMessage = "Unable to locate the artifact metadata file created that must be created by Quarkus in order to run integration tests. ";
if (testLauncher == TestLauncher.MAVEN) {
errorMessage += "Make sure this test is run after 'mvn package'. ";
if (context.getTestClass().isPresent()) {
String testClassName = context.getTestClass().get().getName();
if (testClassName.endsWith("Test")) {
errorMessage += "The easiest way to ensure this is by having the 'maven-failsafe-plugin' run the test instead of the 'maven-surefire-plugin'.";
}
}
} else if (testLauncher == TestLauncher.GRADLE) {
errorMessage += "Make sure this test is run after the 'quarkusBuild' Gradle task.";
} else {
errorMessage += "Make sure this test is run after the Quarkus artifact is built from your build tool.";
}
throw new IllegalStateException(errorMessage);
}
try {
Properties properties = new Properties();
Expand All @@ -246,6 +260,33 @@ static Properties readQuarkusArtifactProperties(ExtensionContext context) {
}
}

private static TestLauncher determineTestLauncher() {
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
int i = stackTrace.length - 1;
TestLauncher testLauncher = TestLauncher.UNKNOWN;
while (true) {
StackTraceElement element = stackTrace[i--];
String className = element.getClassName();
if (className.startsWith("org.apache.maven")) {
testLauncher = TestLauncher.MAVEN;
break;
}
if (className.startsWith("org.gradle")) {
testLauncher = TestLauncher.GRADLE;
}
if (i == 0) {
break;
}
}
return testLauncher;
}

private enum TestLauncher {
MAVEN,
GRADLE,
UNKNOWN
}

static Path determineBuildOutputDirectory(ExtensionContext context) {
String buildOutputDirStr = System.getProperty("build.output.directory");
Path result = null;
Expand Down

0 comments on commit 8cdda6b

Please sign in to comment.