expressionFun,
- ErrorInitializer errorInitializer) {
+ public Builder(String id, Parser parser, ErrorInitializer errorInitializer) {
this.id = id;
this.nodes = new ArrayList<>();
- this.expressionFun = expressionFun;
+ this.parser = parser;
this.errorInitializer = errorInitializer;
}
@@ -229,7 +227,7 @@ SectionBlock.Builder addParameter(String name, String value) {
@Override
public Expression addExpression(String param, String value) {
- Expression expression = expressionFun.apply(value);
+ Expression expression = parser.createSectionBlockExpression(this, value);
if (expressions == null) {
expressions = new LinkedHashMap<>();
}
diff --git a/independent-projects/qute/core/src/main/java/io/quarkus/qute/SectionHelperFactory.java b/independent-projects/qute/core/src/main/java/io/quarkus/qute/SectionHelperFactory.java
index 2af895f7dbcc3..78e902c149940 100644
--- a/independent-projects/qute/core/src/main/java/io/quarkus/qute/SectionHelperFactory.java
+++ b/independent-projects/qute/core/src/main/java/io/quarkus/qute/SectionHelperFactory.java
@@ -140,6 +140,8 @@ default boolean hasParameter(String name) {
* Parse and register an expression for the specified parameter.
*
* A registered expression contributes to the {@link Template#getExpressions()}, i.e. can be validated at build time.
+ *
+ * The origin of the returned expression is the origin of the containing block.
*
* @param param
* @param value
diff --git a/independent-projects/qute/core/src/main/java/io/quarkus/qute/SectionNode.java b/independent-projects/qute/core/src/main/java/io/quarkus/qute/SectionNode.java
index 0467c432651b6..a00d786e357be 100644
--- a/independent-projects/qute/core/src/main/java/io/quarkus/qute/SectionNode.java
+++ b/independent-projects/qute/core/src/main/java/io/quarkus/qute/SectionNode.java
@@ -7,7 +7,6 @@
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletionStage;
-import java.util.function.Function;
import java.util.function.Predicate;
import org.jboss.logging.Logger;
@@ -18,9 +17,9 @@ class SectionNode implements TemplateNode {
private static final Logger LOG = Logger.getLogger("io.quarkus.qute.nodeResolve");
- static Builder builder(String helperName, Origin origin, Function expressionFun,
+ static Builder builder(String helperName, Origin origin, Parser parser,
ErrorInitializer errorFun) {
- return new Builder(helperName, origin, expressionFun, errorFun);
+ return new Builder(helperName, origin, parser, errorFun);
}
final String name;
@@ -110,15 +109,14 @@ static class Builder {
private EngineImpl engine;
private final ErrorInitializer errorInitializer;
- Builder(String helperName, Origin origin, Function expressionFun,
- ErrorInitializer errorInitializer) {
+ Builder(String helperName, Origin origin, Parser parser, ErrorInitializer errorInitializer) {
this.helperName = helperName;
this.origin = origin;
this.blocks = new ArrayList<>();
this.errorInitializer = errorInitializer;
// The main block is always present
addBlock(SectionBlock
- .builder(SectionHelperFactory.MAIN_BLOCK_NAME, expressionFun, errorInitializer)
+ .builder(SectionHelperFactory.MAIN_BLOCK_NAME, parser, errorInitializer)
.setOrigin(origin));
}
diff --git a/independent-projects/qute/core/src/test/java/io/quarkus/qute/IfSectionTest.java b/independent-projects/qute/core/src/test/java/io/quarkus/qute/IfSectionTest.java
index 7d338ad397802..56964eb816fc6 100644
--- a/independent-projects/qute/core/src/test/java/io/quarkus/qute/IfSectionTest.java
+++ b/independent-projects/qute/core/src/test/java/io/quarkus/qute/IfSectionTest.java
@@ -240,6 +240,25 @@ public void testFromageCondition() {
.data("user", "Stef", "target", new Target(ContentStatus.NEW)).render());
}
+ @Test
+ public void testParameterOrigin() {
+ Engine engine = Engine.builder().addDefaults().build();
+ Template template = engine.parse(" {#if item.price > 1}{/if}");
+ List expressions = template.getExpressions();
+ assertEquals(2, expressions.size());
+ for (Expression expression : expressions) {
+ if (expression.isLiteral()) {
+ assertEquals(1, expression.getLiteralValue().getNow(false));
+ assertEquals(1, expression.getOrigin().getLine());
+ assertEquals(3, expression.getOrigin().getLineCharacterStart());
+ } else {
+ assertEquals("item.price", expression.toOriginalString());
+ assertEquals(1, expression.getOrigin().getLine());
+ assertEquals(3, expression.getOrigin().getLineCharacterStart());
+ }
+ }
+ }
+
public static class Target {
public ContentStatus status;
diff --git a/independent-projects/qute/core/src/test/java/io/quarkus/qute/ParserTest.java b/independent-projects/qute/core/src/test/java/io/quarkus/qute/ParserTest.java
index 31b793b7e32a9..48bb33815f9b0 100644
--- a/independent-projects/qute/core/src/test/java/io/quarkus/qute/ParserTest.java
+++ b/independent-projects/qute/core/src/test/java/io/quarkus/qute/ParserTest.java
@@ -157,7 +157,7 @@ public void testLines() {
+ "{/}");
Origin fooItemsOrigin = find(template.getExpressions(), "foo.items").getOrigin();
assertEquals(6, fooItemsOrigin.getLine());
- assertEquals(14, fooItemsOrigin.getLineCharacterStart());
+ assertEquals(1, fooItemsOrigin.getLineCharacterStart());
assertEquals(24, fooItemsOrigin.getLineCharacterEnd());
Origin itemNameOrigin = find(template.getExpressions(), "item.name").getOrigin();
assertEquals(8, itemNameOrigin.getLine());
diff --git a/independent-projects/qute/core/src/test/java/io/quarkus/qute/SetSectionTest.java b/independent-projects/qute/core/src/test/java/io/quarkus/qute/SetSectionTest.java
index 60364077f6c9a..25511136b6c7c 100644
--- a/independent-projects/qute/core/src/test/java/io/quarkus/qute/SetSectionTest.java
+++ b/independent-projects/qute/core/src/test/java/io/quarkus/qute/SetSectionTest.java
@@ -2,6 +2,7 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
+import java.util.List;
import org.junit.jupiter.api.Test;
public class SetSectionTest {
@@ -41,4 +42,23 @@ public void testDefaultValues() {
.data("bar", "42", "baz", "no").render());
}
+ @Test
+ public void testParameterOrigin() {
+ Engine engine = Engine.builder().addDefaults().build();
+ Template template = engine.parse(" {#let item=1 foo=bar}{/let}");
+ List expressions = template.getExpressions();
+ assertEquals(2, expressions.size());
+ for (Expression expression : expressions) {
+ if (expression.isLiteral()) {
+ assertEquals(1, expression.getLiteralValue().getNow(false));
+ assertEquals(1, expression.getOrigin().getLine());
+ assertEquals(3, expression.getOrigin().getLineCharacterStart());
+ } else {
+ assertEquals("bar", expression.toOriginalString());
+ assertEquals(1, expression.getOrigin().getLine());
+ assertEquals(3, expression.getOrigin().getLineCharacterStart());
+ }
+ }
+ }
+
}
diff --git a/independent-projects/resteasy-reactive/server/vertx/src/main/java/org/jboss/resteasy/reactive/server/vertx/ResteasyReactiveOutputStream.java b/independent-projects/resteasy-reactive/server/vertx/src/main/java/org/jboss/resteasy/reactive/server/vertx/ResteasyReactiveOutputStream.java
index 824560d0f5d41..6efb3c817439b 100644
--- a/independent-projects/resteasy-reactive/server/vertx/src/main/java/org/jboss/resteasy/reactive/server/vertx/ResteasyReactiveOutputStream.java
+++ b/independent-projects/resteasy-reactive/server/vertx/src/main/java/org/jboss/resteasy/reactive/server/vertx/ResteasyReactiveOutputStream.java
@@ -236,22 +236,38 @@ private void prepareWrite(ByteBuf buffer, boolean finished) throws IOException {
} else {
context.serverResponse().setResponseHeader(HttpHeaderNames.CONTENT_LENGTH, "" + buffer.readableBytes());
}
- } else if (!contentLengthSet()) {
- request.response().setChunked(true);
+ } else {
+ var contentLengthSet = contentLengthSet();
+ if (contentLengthSet == ContentLengthSetResult.NOT_SET) {
+ request.response().setChunked(true);
+ } else if (contentLengthSet == ContentLengthSetResult.IN_JAX_RS_HEADER) {
+ // we need to make sure the content-length header is copied to Vert.x headers
+ // otherwise we could run into a race condition: see https://github.com/quarkusio/quarkus/issues/26599
+ Object contentLength = context.getResponse().get().getHeaders().getFirst(HttpHeaders.CONTENT_LENGTH);
+ context.serverResponse().setResponseHeader(HttpHeaderNames.CONTENT_LENGTH, contentLength.toString());
+ }
}
}
}
- private boolean contentLengthSet() {
+ private ContentLengthSetResult contentLengthSet() {
if (request.response().headers().contains(HttpHeaderNames.CONTENT_LENGTH)) {
- return true;
+ return ContentLengthSetResult.IN_VERTX_HEADER;
}
LazyResponse lazyResponse = context.getResponse();
if (!lazyResponse.isCreated()) {
- return false;
+ return ContentLengthSetResult.NOT_SET;
}
MultivaluedMap responseHeaders = lazyResponse.get().getHeaders();
- return (responseHeaders != null) && responseHeaders.containsKey(HttpHeaders.CONTENT_LENGTH);
+ return (responseHeaders != null) && responseHeaders.containsKey(HttpHeaders.CONTENT_LENGTH)
+ ? ContentLengthSetResult.IN_JAX_RS_HEADER
+ : ContentLengthSetResult.NOT_SET;
+ }
+
+ private enum ContentLengthSetResult {
+ NOT_SET,
+ IN_VERTX_HEADER,
+ IN_JAX_RS_HEADER
}
/**
diff --git a/independent-projects/resteasy-reactive/server/vertx/src/test/java/org/jboss/resteasy/reactive/server/vertx/test/response/ContentLengthTest.java b/independent-projects/resteasy-reactive/server/vertx/src/test/java/org/jboss/resteasy/reactive/server/vertx/test/response/ContentLengthTest.java
index 2faf6d56d628e..3b2088f806a04 100644
--- a/independent-projects/resteasy-reactive/server/vertx/src/test/java/org/jboss/resteasy/reactive/server/vertx/test/response/ContentLengthTest.java
+++ b/independent-projects/resteasy-reactive/server/vertx/src/test/java/org/jboss/resteasy/reactive/server/vertx/test/response/ContentLengthTest.java
@@ -20,7 +20,7 @@
public class ContentLengthTest {
- private static final int NUMBER_OF_COPIES = 500;
+ private static final int NUMBER_OF_COPIES = 1000;
@RegisterExtension
static ResteasyReactiveUnitTest runner = new ResteasyReactiveUnitTest()
diff --git a/integration-tests/hibernate-reactive-postgresql/src/main/java/io/quarkus/it/hibernate/reactive/postgresql/HibernateReactiveTestEndpointFetchLazy.java b/integration-tests/hibernate-reactive-postgresql/src/main/java/io/quarkus/it/hibernate/reactive/postgresql/HibernateReactiveTestEndpointFetchLazy.java
index ff1b103592e0a..c0dcda200b2f5 100644
--- a/integration-tests/hibernate-reactive-postgresql/src/main/java/io/quarkus/it/hibernate/reactive/postgresql/HibernateReactiveTestEndpointFetchLazy.java
+++ b/integration-tests/hibernate-reactive-postgresql/src/main/java/io/quarkus/it/hibernate/reactive/postgresql/HibernateReactiveTestEndpointFetchLazy.java
@@ -34,6 +34,14 @@ public Uni> findBooksWithMutiny(@PathParam("authorId") Integer
.chain(author -> Mutiny.fetch(author.getBooks()));
}
+ @GET
+ @Path("/getReferenceBooksWithMutiny/{authorId}")
+ public Uni> getReferenceBooksWithMutiny(@PathParam("authorId") Integer authorId) {
+ return mutinySession
+ .fetch(mutinySession.getReference(Author.class, authorId))
+ .chain(author -> Mutiny.fetch(author.getBooks()));
+ }
+
@POST
@Path("/prepareDb")
public Uni prepareDb() {
diff --git a/integration-tests/hibernate-reactive-postgresql/src/test/java/io/quarkus/it/hibernate/reactive/postgresql/HibernateReactiveFetchLazyTest.java b/integration-tests/hibernate-reactive-postgresql/src/test/java/io/quarkus/it/hibernate/reactive/postgresql/HibernateReactiveFetchLazyTest.java
index 1cb288ff8602f..f2ee76ed68657 100644
--- a/integration-tests/hibernate-reactive-postgresql/src/test/java/io/quarkus/it/hibernate/reactive/postgresql/HibernateReactiveFetchLazyTest.java
+++ b/integration-tests/hibernate-reactive-postgresql/src/test/java/io/quarkus/it/hibernate/reactive/postgresql/HibernateReactiveFetchLazyTest.java
@@ -18,6 +18,20 @@
@TestHTTPEndpoint(HibernateReactiveTestEndpointFetchLazy.class)
public class HibernateReactiveFetchLazyTest {
+ @Test
+ public void fetchAfterGetReferenceWithMutiny() {
+ RestAssured.when()
+ .post("/prepareDb")
+ .then()
+ .body(is("Neal Stephenson"));
+
+ Response response = RestAssured.when()
+ .get("/getReferenceBooksWithMutiny/567")
+ .then()
+ .extract().response();
+ assertTitles(response, "Cryptonomicon", "Snow Crash");
+ }
+
@Test
public void fetchAfterFindWithMutiny() {
RestAssured.when()
diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/resources/openshift-v3.properties b/integration-tests/kubernetes/quarkus-standard-way/src/test/resources/openshift-v3.properties
index 22bc2bebdb904..dbeb5652f7191 100644
--- a/integration-tests/kubernetes/quarkus-standard-way/src/test/resources/openshift-v3.properties
+++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/resources/openshift-v3.properties
@@ -1,2 +1,4 @@
quarkus.kubernetes.deployment-target=openshift
-quarkus.openshift.flavor=v3
\ No newline at end of file
+quarkus.openshift.flavor=v3
+# used in order to ensure that the non-openshift label does not interfere with the openshift manifest generation
+quarkus.knative.labels."app.openshift.io/runtime"=test
diff --git a/integration-tests/main/src/test/java/io/quarkus/it/main/QuarkusTestCallbacksTestCase.java b/integration-tests/main/src/test/java/io/quarkus/it/main/QuarkusTestCallbacksTestCase.java
index 80983c0f53bc0..670422528a9e8 100644
--- a/integration-tests/main/src/test/java/io/quarkus/it/main/QuarkusTestCallbacksTestCase.java
+++ b/integration-tests/main/src/test/java/io/quarkus/it/main/QuarkusTestCallbacksTestCase.java
@@ -23,7 +23,7 @@
import io.quarkus.test.junit.QuarkusTest;
/**
- * The purpose of this test is simply to ensure that {@link SimpleAnnotationCheckerBeforeEachCallback}
+ * The purpose of this test is simply to ensure that {@link TestContextCheckerBeforeEachCallback}
* can read {@code @TestAnnotation} without issue.
* Also checks that {@link SimpleAnnotationCheckerBeforeClassCallback} is executed properly
*/
@@ -69,7 +69,7 @@ private void checkBeforeOrAfterEachTestInfo(TestInfo testInfo, String unexpected
@TestAnnotation
@Order(1)
public void testTestMethodHasAnnotation() {
- assertTrue(SimpleAnnotationCheckerBeforeEachCallback.testAnnotationChecked);
+ assertTrue(TestContextCheckerBeforeEachCallback.testAnnotationChecked);
}
@Test
diff --git a/integration-tests/main/src/test/java/io/quarkus/it/main/QuarkusTestNestedTestCase.java b/integration-tests/main/src/test/java/io/quarkus/it/main/QuarkusTestNestedTestCase.java
index 57ab941d663c6..479600280ca33 100644
--- a/integration-tests/main/src/test/java/io/quarkus/it/main/QuarkusTestNestedTestCase.java
+++ b/integration-tests/main/src/test/java/io/quarkus/it/main/QuarkusTestNestedTestCase.java
@@ -59,6 +59,7 @@ void test() {
assertEquals(0, COUNT_TEST.getAndIncrement(), "COUNT_TEST");
assertEquals(0, COUNT_AFTER_EACH.get(), "COUNT_AFTER_EACH");
assertEquals(0, COUNT_AFTER_ALL.get(), "COUNT_AFTER_ALL");
+ assertEquals(0, TestContextCheckerBeforeEachCallback.OUTER_INSTANCES.size(), "Found unexpected outer instances");
}
@Nested
@@ -93,6 +94,18 @@ void testTwo() {
assertEquals(0, COUNT_AFTER_ALL.get(), "COUNT_AFTER_ALL");
}
+ @Test
+ @Order(3)
+ void testOuterInstancesInBeforeEach() {
+ assertEquals(1, TestContextCheckerBeforeEachCallback.OUTER_INSTANCES.size());
+ }
+
+ @Test
+ @Order(4)
+ void testOuterInstancesInAfterEach() {
+ assertEquals(1, TestContextCheckerAfterEachCallback.OUTER_INSTANCES.size());
+ }
+
@Test
void testInnerAndOuterValues() {
assertEquals(EXPECTED_INNER_VALUE, innerValue);
@@ -122,7 +135,6 @@ void beforeEach() {
@Test
@Order(1)
void testOne() {
- // assertEquals(1, SECOND_LEVEL_COUNTER.get(), "SECOND_LEVEL_COUNTER");
assertEquals(1, SECOND_LEVEL_COUNTER.get(), "SECOND_LEVEL_COUNTER");
}
@@ -134,6 +146,24 @@ void testSecondLevelAndInnerAndOuterValues() {
assertEquals(EXPECTED_OUTER_VALUE, outerValue);
assertEquals(EXPECTED_SECOND_LEVEL_FIRST_INNER_VALUE, secondLevelInnerValue);
}
+
+ @Test
+ @Order(3)
+ void testOuterInstancesInBeforeEach() {
+ assertEquals(2, TestContextCheckerBeforeEachCallback.OUTER_INSTANCES.size());
+ }
+
+ @Test
+ @Order(4)
+ void testOuterInstancesInAfterEach() {
+ assertEquals(2, TestContextCheckerAfterEachCallback.OUTER_INSTANCES.size());
+ }
+
+ @Test
+ @Order(5)
+ void testOuterInstancesInAfterAll() {
+ assertEquals(1, TestContextCheckerAfterAllCallback.OUTER_INSTANCES.size());
+ }
}
}
@@ -185,9 +215,9 @@ void afterEach() {
@AfterAll
static void afterAll() {
assertEquals(1, COUNT_BEFORE_ALL.get(), "COUNT_BEFORE_ALL");
- assertEquals(15, COUNT_BEFORE_EACH.get(), "COUNT_BEFORE_EACH");
+ assertEquals(25, COUNT_BEFORE_EACH.get(), "COUNT_BEFORE_EACH");
assertEquals(4, COUNT_TEST.get(), "COUNT_TEST");
- assertEquals(15, COUNT_AFTER_EACH.get(), "COUNT_AFTER_EACH");
+ assertEquals(25, COUNT_AFTER_EACH.get(), "COUNT_AFTER_EACH");
assertEquals(0, COUNT_AFTER_ALL.getAndIncrement(), "COUNT_AFTER_ALL");
}
}
diff --git a/integration-tests/main/src/test/java/io/quarkus/it/main/TestContextCheckerAfterAllCallback.java b/integration-tests/main/src/test/java/io/quarkus/it/main/TestContextCheckerAfterAllCallback.java
new file mode 100644
index 0000000000000..ba8af179ebfc2
--- /dev/null
+++ b/integration-tests/main/src/test/java/io/quarkus/it/main/TestContextCheckerAfterAllCallback.java
@@ -0,0 +1,18 @@
+package io.quarkus.it.main;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import io.quarkus.test.junit.callback.QuarkusTestAfterAllCallback;
+import io.quarkus.test.junit.callback.QuarkusTestContext;
+
+public class TestContextCheckerAfterAllCallback implements QuarkusTestAfterAllCallback {
+
+ public static final List