Skip to content

Commit

Permalink
Merge pull request #25610 from gsmet/2.9.1-backports-3
Browse files Browse the repository at this point in the history
2.9.1 backports 3
  • Loading branch information
gsmet authored May 17, 2022
2 parents 5888e99 + c10cb3e commit a35de75
Show file tree
Hide file tree
Showing 19 changed files with 335 additions and 75 deletions.
2 changes: 1 addition & 1 deletion bom/application/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@
<classmate.version>1.5.1</classmate.version>
<hibernate-orm.version>5.6.9.Final</hibernate-orm.version> <!-- When updating, align bytebuddy.version to Hibernate needs as well (just below): -->
<bytebuddy.version>1.12.9</bytebuddy.version> <!-- Version controlled by Hibernate ORM's needs -->
<hibernate-reactive.version>1.1.4.Final</hibernate-reactive.version>
<hibernate-reactive.version>1.1.5.Final</hibernate-reactive.version>
<hibernate-validator.version>6.2.3.Final</hibernate-validator.version>
<hibernate-search.version>6.1.3.Final</hibernate-search.version>
<narayana.version>5.12.6.Final</narayana.version>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ private Project findDeploymentProject(Project project, QuarkusExtensionConfigura
}
if (deploymentProject == null) {
project.getLogger().warn("Unable to find deployment project with name: " + deploymentProjectName
+ ". You can configure the deployment project name by setting the 'deploymentArtifact' property in the plugin extension.");
+ ". You can configure the deployment project name by setting the 'deploymentModule' property in the plugin extension.");
}
}
return deploymentProject;
Expand Down
24 changes: 16 additions & 8 deletions docs/src/main/asciidoc/flyway.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Quarkus provides first class support for using Flyway as will be explained in th

== Setting up support for Flyway

To start using Flyway with your project, you just need to:
As shown in the <<developing-with-flyway>> section, to start using Flyway with your project, you just need to:

* add your migrations to the `{migrations-path}` folder as you usually do with Flyway
* activate the `migrate-at-start` option to migrate the schema automatically or inject the `Flyway` object and run
Expand Down Expand Up @@ -77,6 +77,7 @@ Also, you can customize the Flyway behaviour by using the following properties:

include::{generated-dir}/config/quarkus-flyway.adoc[opts=optional, leveloffset=+1]

== Developing with Flyway

The following is an example for the `{config-file}` file:

Expand All @@ -88,10 +89,10 @@ quarkus.datasource.username=sarah
quarkus.datasource.password=connor
quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5432/mydatabase
# Flyway minimal config properties
# Run Flyway migrations automatically
quarkus.flyway.migrate-at-start=true
# Flyway optional config properties
# More Flyway configuration options
# quarkus.flyway.baseline-on-migrate=true
# quarkus.flyway.baseline-version=1.0.0
# quarkus.flyway.baseline-description=Initial version
Expand All @@ -116,7 +117,12 @@ INSERT INTO quarkus(id, name)
VALUES (1, 'QUARKED');
----

Now you can start your application and Quarkus will run the Flyway's migrate method according to your config:
Now you can start your application and Quarkus will run the Flyway's
migrate method according to your config.

NOTE: With `quarkus.flyway.migrate-at-start=true`, as in the example
above, Quarkus will execute the Flyway migration as part of the
xref:lifecycle.adoc[application startup].

[source,java]
----
Expand All @@ -132,9 +138,14 @@ public class MigrationService {
}
}
----

<1> Inject the Flyway object if you want to use it directly

TIP: In dev-mode Quarkus will automatically restart the application if
any of the existing migration scripts get modified. If you want to take
advantage of this while developing and testing new migration scripts,
you will want to set `%dev.quarkus.flyway.clean-at-start=true`, so that
Flyway actually runs the modified migration.

== Multiple datasources

Flyway can be configured for multiple datasources.
Expand Down Expand Up @@ -182,9 +193,6 @@ NOTE: Without configuration, Flyway is set up for every datasource using the def

In case you are interested in using the `Flyway` object directly, you can inject it as follows:

NOTE: If you enabled the `quarkus.flyway.migrate-at-start` property, by the time you use the Flyway instance,
Quarkus will already have run the migrate operation

[source,java]
----
@ApplicationScoped
Expand Down
2 changes: 1 addition & 1 deletion docs/src/main/asciidoc/hibernate-orm.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,7 @@ link in the Flyway pane. Hit the `Create Initial Migration` button and the follo
- A `db/migration/V1.0.0__\{appname\}.sql` file will be created, containing the SQL Hibernate is running to generate the schema
- `quarkus.flyway.baseline-on-migrate` will be set, telling Flyway to automatically create its baseline tables
- `quarkus.flyway.migrate-at-start` will be set, telling Flyway to automatically apply migrations on application startup
- `%dev.quarkus.flyway.clean-at-start` and ``%test.quarkus.flyway.clean-at-start` will be set, to clean the DB after reload in dev/test mode
- `%dev.quarkus.flyway.clean-at-start` and `%test.quarkus.flyway.clean-at-start` will be set, to clean the DB after reload in dev/test mode

WARNING: This button is simply a convenience to quickly get you started with Flyway, it is up to you to determine how you want to
manage your database schemas in production. In particular the `migrate-at-start` setting may not be right for all environments.
Expand Down
4 changes: 2 additions & 2 deletions docs/src/main/asciidoc/writing-extensions.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -546,7 +546,7 @@ Please refer to https://github.com/quarkusio/quarkus/blob/{quarkus-version}/devt
You will need to apply the `io.quarkus.extension` plugin in the `runtime` module of your extension project.
The plugin includes the `extensionDescriptor` task that will generate `META-INF/quarkus-extension.properties` and `META-INF/quarkus-extension.yml` files.
The plugin also enables the `io.quarkus:quarkus-extension-processor` annotation processor in both `deployment` and `runtime` modules.
The name of the deployment module can be configured in the plugin by setting the `deploymentArtifact` property. The property is set to `deployment` by default:
The name of the deployment module can be configured in the plugin by setting the `deploymentModule` property. The property is set to `deployment` by default:

[source,groovy,subs=attributes+]
----
Expand All @@ -556,7 +556,7 @@ plugins {
}
quarkusExtension {
deploymentArtifact = 'deployment'
deploymentModule = 'deployment'
}
dependencies {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import io.quarkus.deployment.annotations.Record;
import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
import io.quarkus.deployment.builditem.FeatureBuildItem;
import io.quarkus.deployment.builditem.HotDeploymentWatchedFileBuildItem;
import io.quarkus.deployment.builditem.IndexDependencyBuildItem;
import io.quarkus.deployment.builditem.ServiceStartBuildItem;
import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem;
Expand Down Expand Up @@ -81,6 +82,7 @@ IndexDependencyBuildItem indexFlyway() {
MigrationStateBuildItem build(BuildProducer<FeatureBuildItem> featureProducer,
BuildProducer<NativeImageResourceBuildItem> resourceProducer,
BuildProducer<ReflectiveClassBuildItem> reflectiveClassProducer,
BuildProducer<HotDeploymentWatchedFileBuildItem> hotDeploymentProducer,
FlywayRecorder recorder,
RecorderContext context,
CombinedIndexBuildItem combinedIndexBuildItem,
Expand All @@ -107,6 +109,9 @@ MigrationStateBuildItem build(BuildProducer<FeatureBuildItem> featureProducer,

Collection<String> applicationMigrations = applicationMigrationsToDs.values().stream().collect(HashSet::new,
AbstractCollection::addAll, HashSet::addAll);
for (String applicationMigration : applicationMigrations) {
hotDeploymentProducer.produce(new HotDeploymentWatchedFileBuildItem(applicationMigration));
}
recorder.setApplicationMigrationFiles(applicationMigrations);

Set<Class<? extends JavaMigration>> javaMigrationClasses = new HashSet<>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package io.quarkus.flyway.test;

import static org.hamcrest.Matchers.is;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.function.Function;

import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.agroal.api.AgroalDataSource;
import io.quarkus.test.QuarkusDevModeTest;
import io.restassured.RestAssured;

public class FlywayDevModeModifyMigrationTest {

@RegisterExtension
static final QuarkusDevModeTest config = new QuarkusDevModeTest()
.withApplicationRoot((jar) -> jar
.addClasses(RowCountEndpoint.class)
.addAsResource("db/migration/V1.0.0__Quarkus.sql")
.addAsResource("clean-and-migrate-at-start-config.properties", "application.properties"));

@Test
public void testModifyingExistingMigrationScriptCausesRestart() {
RestAssured.get("/row-count").then().statusCode(200).body(is("0"));
config.modifyResourceFile("db/migration/V1.0.0__Quarkus.sql", new Function<String, String>() {
@Override
public String apply(String s) {
return s + '\n' + "INSERT INTO quarked_flyway VALUES (1001, 'test')";
}
});
RestAssured.get("/row-count").then().statusCode(200).body(is("1"));
}

@Path("/row-count")
public static class RowCountEndpoint {

@Inject
AgroalDataSource dataSource;

@GET
public int rowCount() throws SQLException {
try (Connection connection = dataSource.getConnection(); Statement stat = connection.createStatement()) {
try (ResultSet countQuery = stat.executeQuery("select count(1) from quarked_flyway")) {
return countQuery.first() ? countQuery.getInt(1) : 0;
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public void testApplicationJsonMediaType() {
Response response = base.request().get();
Assertions.assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
String body = response.readEntity(String.class);
Assertions.assertEquals(response.getHeaderString("Content-Type"), "application/json");
Assertions.assertEquals(response.getHeaderString("Content-Type"), "application/json;charset=UTF-8");
} catch (Exception e) {
throw new RuntimeException(e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public void testMatch() throws Exception {
WebTarget base = client.target(generateURL("/match"));
Response response = base.request().header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
.get();
Assertions.assertEquals("text/html", response.getHeaders().getFirst("Content-Type"));
Assertions.assertEquals("text/html;charset=UTF-8", response.getHeaders().getFirst("Content-Type"));
String res = response.readEntity(String.class);
Assertions.assertEquals("*/*", res, "Wrong response content");
response.close();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,52 @@ public void handleUnmappedException(Throwable throwable) {
private <E extends Throwable> RuntimeException sneakyThrow(Throwable e) throws E {
throw (E) e;
}

/**
* The implementation looks like it makes no sense, but it in fact does make sense from a performance perspective.
* The idea is to reduce the use instances of megamorphic calls into a series of instance checks and monomorphic calls.
* The rationale behind this is fully explored in
* https://shipilev.net/blog/2015/black-magic-method-dispatch/#_cheating_the_runtime_2
* and this specific instance has been verified experimentally to result in better performance.
*/
@Override
protected void invokeHandler(int pos) throws Exception {
var handler = handlers[pos];
if (handler instanceof org.jboss.resteasy.reactive.server.handlers.MatrixParamHandler) {
handler.handle(this);
} else if (handler instanceof io.quarkus.resteasy.reactive.server.runtime.security.SecurityContextOverrideHandler) {
handler.handle(this);
} else if (handler instanceof org.jboss.resteasy.reactive.server.handlers.RestInitialHandler) {
handler.handle(this);
} else if (handler instanceof org.jboss.resteasy.reactive.server.handlers.ClassRoutingHandler) {
handler.handle(this);
} else if (handler instanceof org.jboss.resteasy.reactive.server.handlers.AbortChainHandler) {
handler.handle(this);
} else if (handler instanceof org.jboss.resteasy.reactive.server.handlers.NonBlockingHandler) {
handler.handle(this);
} else if (handler instanceof org.jboss.resteasy.reactive.server.handlers.BlockingHandler) {
handler.handle(this);
} else if (handler instanceof org.jboss.resteasy.reactive.server.handlers.ResourceRequestFilterHandler) {
handler.handle(this);
} else if (handler instanceof org.jboss.resteasy.reactive.server.handlers.InputHandler) {
handler.handle(this);
} else if (handler instanceof org.jboss.resteasy.reactive.server.handlers.RequestDeserializeHandler) {
handler.handle(this);
} else if (handler instanceof org.jboss.resteasy.reactive.server.handlers.ParameterHandler) {
handler.handle(this);
} else if (handler instanceof org.jboss.resteasy.reactive.server.handlers.InstanceHandler) {
handler.handle(this);
} else if (handler instanceof org.jboss.resteasy.reactive.server.handlers.InvocationHandler) {
handler.handle(this);
} else if (handler instanceof org.jboss.resteasy.reactive.server.handlers.FixedProducesHandler) {
handler.handle(this);
} else if (handler instanceof org.jboss.resteasy.reactive.server.handlers.ResponseHandler) {
handler.handle(this);
} else if (handler instanceof org.jboss.resteasy.reactive.server.handlers.ResponseWriterHandler) {
handler.handle(this);
} else {
// megamorphic call for other handlers
handler.handle(this);
}
}
}
Loading

0 comments on commit a35de75

Please sign in to comment.