diff --git a/docs/src/main/asciidoc/reactive-routes.adoc b/docs/src/main/asciidoc/reactive-routes.adoc index e10b1c7c73e1c..d171a76f8265c 100644 --- a/docs/src/main/asciidoc/reactive-routes.adoc +++ b/docs/src/main/asciidoc/reactive-routes.adoc @@ -105,15 +105,24 @@ The `@Route` annotation is repeatable and so you can declare several routes for [source,java] ---- -@Route(path = "/first") +@Route(path = "/first") <1> @Route(path = "/second") public void route(RoutingContext rc) { // ... } ---- +<1> Each route can use different paths, methods... -Each route can use different paths, methods... +If no content-type header is set then we will try to use the most acceptable content type as defined by `io.vertx.ext.web.RoutingContext.getAcceptableContentType()`. +[source,java] +---- +@Route(path = "/person", produces = "text/html") <1> +String person() { + // ... +} +---- +<1> If the `accept` header matches `text/html` we set the content type automatically. === Handling conflicting routes diff --git a/extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/QuteProcessor.java b/extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/QuteProcessor.java index 1e6bc53ee4e27..5efef354c22ee 100644 --- a/extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/QuteProcessor.java +++ b/extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/QuteProcessor.java @@ -71,7 +71,6 @@ import io.quarkus.deployment.builditem.ServiceStartBuildItem; import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem; import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem; -import io.quarkus.deployment.builditem.nativeimage.ServiceProviderBuildItem; import io.quarkus.deployment.util.JandexUtil; import io.quarkus.gizmo.ClassOutput; import io.quarkus.qute.Engine; @@ -81,7 +80,6 @@ import io.quarkus.qute.LoopSectionHelper; import io.quarkus.qute.ParserHelper; import io.quarkus.qute.ParserHook; -import io.quarkus.qute.PublisherFactory; import io.quarkus.qute.ResultNode; import io.quarkus.qute.SectionHelper; import io.quarkus.qute.SectionHelperFactory; @@ -99,7 +97,6 @@ import io.quarkus.qute.deployment.TypeInfos.Info; import io.quarkus.qute.generator.ExtensionMethodGenerator; import io.quarkus.qute.generator.ValueResolverGenerator; -import io.quarkus.qute.mutiny.MutinyPublisherFactory; import io.quarkus.qute.runtime.EngineProducer; import io.quarkus.qute.runtime.QuteConfig; import io.quarkus.qute.runtime.QuteRecorder; @@ -854,11 +851,6 @@ TemplateVariantsBuildItem collectTemplateVariants(List te return new TemplateVariantsBuildItem(baseToVariants); } - @BuildStep - ServiceProviderBuildItem registerPublisherFactory() { - return new ServiceProviderBuildItem(PublisherFactory.class.getName(), MutinyPublisherFactory.class.getName()); - } - @BuildStep void excludeTypeChecks(BuildProducer excludes) { // Exclude all checks that involve built-in value resolvers diff --git a/extensions/qute/deployment/src/test/java/io/quarkus/qute/deployment/PublisherTest.java b/extensions/qute/deployment/src/test/java/io/quarkus/qute/deployment/MultiTest.java similarity index 77% rename from extensions/qute/deployment/src/test/java/io/quarkus/qute/deployment/PublisherTest.java rename to extensions/qute/deployment/src/test/java/io/quarkus/qute/deployment/MultiTest.java index 2681e96e138dc..cdca6de3376e5 100644 --- a/extensions/qute/deployment/src/test/java/io/quarkus/qute/deployment/PublisherTest.java +++ b/extensions/qute/deployment/src/test/java/io/quarkus/qute/deployment/MultiTest.java @@ -1,7 +1,6 @@ package io.quarkus.qute.deployment; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; import java.math.BigDecimal; import java.math.RoundingMode; @@ -13,14 +12,13 @@ import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; -import org.reactivestreams.Publisher; import io.quarkus.qute.Template; import io.quarkus.qute.TemplateData; import io.quarkus.test.QuarkusUnitTest; import io.smallrye.mutiny.Multi; -public class PublisherTest { +public class MultiTest { @RegisterExtension static final QuarkusUnitTest config = new QuarkusUnitTest() @@ -33,11 +31,10 @@ public class PublisherTest { Template foo; @Test - public void testTemplateData() { - Publisher publisher = foo.data("roundingMode", RoundingMode.HALF_UP) - .data("foo", new TemplateDataTest.Foo(new BigDecimal("123.4563"))).publisher(); - assertTrue(publisher instanceof Multi); - assertEquals("123.4563 is not 123.46", Multi.createFrom().publisher(publisher) + public void testCreateMulti() { + Multi multi = foo.data("roundingMode", RoundingMode.HALF_UP) + .data("foo", new TemplateDataTest.Foo(new BigDecimal("123.4563"))).createMulti(); + assertEquals("123.4563 is not 123.46", multi .collectItems().in(StringBuffer::new, StringBuffer::append) .onItem().apply(StringBuffer::toString) .await().indefinitely()); diff --git a/extensions/qute/runtime/pom.xml b/extensions/qute/runtime/pom.xml index 9b5c02b92af5e..ee47f8defd956 100644 --- a/extensions/qute/runtime/pom.xml +++ b/extensions/qute/runtime/pom.xml @@ -27,10 +27,6 @@ io.quarkus.qute qute-core - - io.quarkus.qute - qute-mutiny - org.junit.jupiter junit-jupiter diff --git a/extensions/qute/runtime/src/main/java/io/quarkus/qute/runtime/TemplateProducer.java b/extensions/qute/runtime/src/main/java/io/quarkus/qute/runtime/TemplateProducer.java index 62dfab8a0015d..a7d43e7d745f0 100644 --- a/extensions/qute/runtime/src/main/java/io/quarkus/qute/runtime/TemplateProducer.java +++ b/extensions/qute/runtime/src/main/java/io/quarkus/qute/runtime/TemplateProducer.java @@ -19,7 +19,6 @@ import javax.inject.Singleton; import org.jboss.logging.Logger; -import org.reactivestreams.Publisher; import io.quarkus.qute.Engine; import io.quarkus.qute.Expression; @@ -29,6 +28,7 @@ import io.quarkus.qute.Variant; import io.quarkus.qute.api.ResourcePath; import io.quarkus.qute.runtime.QuteRecorder.QuteContext; +import io.smallrye.mutiny.Multi; @Singleton public class TemplateProducer { @@ -154,8 +154,8 @@ public CompletionStage renderAsync() { } @Override - public Publisher publisher() { - return templateInstance().publisher(); + public Multi createMulti() { + return templateInstance().createMulti(); } @Override diff --git a/extensions/vertx-web/deployment/src/main/java/io/quarkus/vertx/web/deployment/Methods.java b/extensions/vertx-web/deployment/src/main/java/io/quarkus/vertx/web/deployment/Methods.java index 554c8137af547..22102021b2bd8 100644 --- a/extensions/vertx-web/deployment/src/main/java/io/quarkus/vertx/web/deployment/Methods.java +++ b/extensions/vertx-web/deployment/src/main/java/io/quarkus/vertx/web/deployment/Methods.java @@ -19,6 +19,7 @@ import io.quarkus.vertx.web.runtime.MultiJsonArraySupport; import io.quarkus.vertx.web.runtime.MultiSseSupport; import io.quarkus.vertx.web.runtime.MultiSupport; +import io.quarkus.vertx.web.runtime.RouteHandlers; import io.smallrye.mutiny.Multi; import io.smallrye.mutiny.Uni; import io.smallrye.mutiny.groups.UniSubscribe; @@ -136,6 +137,9 @@ class Methods { CreationalContext.class); static final MethodDescriptor OBJECT_CONSTRUCTOR = MethodDescriptor.ofConstructor(Object.class); + static final MethodDescriptor ROUTE_HANDLERS_SET_CONTENT_TYPE = MethodDescriptor + .ofMethod(RouteHandlers.class, "setContentType", void.class, RoutingContext.class); + private Methods() { // Avoid direct instantiation } diff --git a/extensions/vertx-web/deployment/src/main/java/io/quarkus/vertx/web/deployment/VertxWebProcessor.java b/extensions/vertx-web/deployment/src/main/java/io/quarkus/vertx/web/deployment/VertxWebProcessor.java index a8b9289ee1afb..7b56b67208bfa 100644 --- a/extensions/vertx-web/deployment/src/main/java/io/quarkus/vertx/web/deployment/VertxWebProcessor.java +++ b/extensions/vertx-web/deployment/src/main/java/io/quarkus/vertx/web/deployment/VertxWebProcessor.java @@ -530,10 +530,13 @@ void implementInvoke(HandlerDescriptor descriptor, BeanInfo bean, MethodInfo met // Invoke the business method handler ResultHandle res = invoke.invokeVirtualMethod(methodDescriptor, beanInstanceHandle, paramHandles); + // If no content-type header is set then try to use the most acceptable content type + invoke.invokeStaticMethod(Methods.ROUTE_HANDLERS_SET_CONTENT_TYPE, routingContext); + // Get the response: HttpServerResponse response = rc.response() - ResultHandle response = invoke.invokeInterfaceMethod(Methods.RESPONSE, routingContext); MethodDescriptor end = Methods.getEndMethodForContentType(descriptor); if (descriptor.isReturningUni()) { + ResultHandle response = invoke.invokeInterfaceMethod(Methods.RESPONSE, routingContext); // The method returns a Uni. // We subscribe to this Uni and write the provided item in the HTTP response // If the method returned null, we fail @@ -568,7 +571,7 @@ void implementInvoke(HandlerDescriptor descriptor, BeanInfo bean, MethodInfo met } else if (descriptor.getContentType() != null) { // The method returns "something" in a synchronous manner, write it into the response - + ResultHandle response = invoke.invokeInterfaceMethod(Methods.RESPONSE, routingContext); // If the method returned null, we fail // If the method returns string or buffer, the response.end method is used to write the response // If the method returns an object, the result is mapped to JSON and written into the response diff --git a/extensions/vertx-web/runtime/src/main/java/io/quarkus/vertx/web/Route.java b/extensions/vertx-web/runtime/src/main/java/io/quarkus/vertx/web/Route.java index a8b0ef5eae591..d4221b7252e7f 100644 --- a/extensions/vertx-web/runtime/src/main/java/io/quarkus/vertx/web/Route.java +++ b/extensions/vertx-web/runtime/src/main/java/io/quarkus/vertx/web/Route.java @@ -10,6 +10,7 @@ import io.vertx.core.Handler; import io.vertx.core.http.HttpMethod; import io.vertx.ext.web.Router; +import io.vertx.ext.web.RoutingContext; /** * This annotation can be used to configure a reactive route in a declarative way. @@ -74,8 +75,11 @@ /** * Used for content-based routing. + *

+ * If no {@code Content-Type} header is set then try to use the most acceptable content type. * * @see io.vertx.ext.web.Route#produces(String) + * @see RoutingContext#getAcceptableContentType() * @return the produced content types */ String[] produces() default {}; diff --git a/extensions/vertx-web/runtime/src/main/java/io/quarkus/vertx/web/runtime/RouteHandlers.java b/extensions/vertx-web/runtime/src/main/java/io/quarkus/vertx/web/runtime/RouteHandlers.java index 4e1978f80b5e6..a2f37cac5b35d 100644 --- a/extensions/vertx-web/runtime/src/main/java/io/quarkus/vertx/web/runtime/RouteHandlers.java +++ b/extensions/vertx-web/runtime/src/main/java/io/quarkus/vertx/web/runtime/RouteHandlers.java @@ -5,12 +5,29 @@ import io.quarkus.arc.Arc; import io.quarkus.arc.impl.LazyValue; import io.quarkus.security.identity.SecurityIdentity; +import io.vertx.core.http.HttpServerResponse; +import io.vertx.ext.web.RoutingContext; -final class RouteHandlers { +public final class RouteHandlers { + + private RouteHandlers() { + } + + static final String CONTENT_TYPE = "content-type"; private static final LazyValue> SECURITY_IDENTITY_EVENT = new LazyValue<>( RouteHandlers::createEvent); + public static void setContentType(RoutingContext context) { + HttpServerResponse response = context.response(); + if (response.headers().get(CONTENT_TYPE) == null) { + String acceptableContentType = context.getAcceptableContentType(); + if (acceptableContentType != null) { + response.putHeader(CONTENT_TYPE, acceptableContentType); + } + } + } + static void fireSecurityIdentity(SecurityIdentity identity) { SECURITY_IDENTITY_EVENT.get().fire(identity); } diff --git a/independent-projects/qute/core/pom.xml b/independent-projects/qute/core/pom.xml index 81dc90e00f44c..1053950850c13 100644 --- a/independent-projects/qute/core/pom.xml +++ b/independent-projects/qute/core/pom.xml @@ -20,8 +20,8 @@ jboss-logging - org.reactivestreams - reactive-streams + io.smallrye.reactive + mutiny org.junit.jupiter diff --git a/independent-projects/qute/core/src/main/java/io/quarkus/qute/EngineImpl.java b/independent-projects/qute/core/src/main/java/io/quarkus/qute/EngineImpl.java index 3042d00dbe311..58b832d56c075 100644 --- a/independent-projects/qute/core/src/main/java/io/quarkus/qute/EngineImpl.java +++ b/independent-projects/qute/core/src/main/java/io/quarkus/qute/EngineImpl.java @@ -10,17 +10,13 @@ import java.util.Collections; import java.util.Comparator; import java.util.HashMap; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.ServiceLoader; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; import java.util.function.Function; import java.util.function.Predicate; -import java.util.stream.Collectors; -import java.util.stream.StreamSupport; import org.jboss.logging.Logger; /** @@ -38,7 +34,6 @@ class EngineImpl implements Engine { private final Map templates; private final List locators; private final List resultMappers; - private final PublisherFactory publisherFactory; private final AtomicLong idGenerator = new AtomicLong(0); private final List parserHooks; final boolean removeStandaloneLines; @@ -50,18 +45,6 @@ class EngineImpl implements Engine { this.evaluator = new EvaluatorImpl(this.valueResolvers); this.templates = new ConcurrentHashMap<>(); this.locators = sort(builder.locators); - ServiceLoader loader = ServiceLoader.load(PublisherFactory.class); - Iterator iterator = loader.iterator(); - if (iterator.hasNext()) { - this.publisherFactory = iterator.next(); - } else { - this.publisherFactory = null; - } - if (iterator.hasNext()) { - throw new IllegalStateException( - "Multiple reactive factories found: " + StreamSupport.stream(loader.spliterator(), false) - .map(Object::getClass).map(Class::getName).collect(Collectors.joining(","))); - } this.resultMappers = sort(builder.resultMappers); this.sectionHelperFunc = builder.sectionHelperFunc; this.parserHooks = ImmutableList.copyOf(builder.parserHooks); @@ -129,10 +112,6 @@ public void removeTemplates(Predicate test) { templates.keySet().removeIf(test); } - PublisherFactory getPublisherFactory() { - return publisherFactory; - } - String generateId() { return "" + idGenerator.incrementAndGet(); } diff --git a/independent-projects/qute/core/src/main/java/io/quarkus/qute/PublisherFactory.java b/independent-projects/qute/core/src/main/java/io/quarkus/qute/PublisherFactory.java deleted file mode 100644 index 7fadef2e934cb..0000000000000 --- a/independent-projects/qute/core/src/main/java/io/quarkus/qute/PublisherFactory.java +++ /dev/null @@ -1,12 +0,0 @@ -package io.quarkus.qute; - -import org.reactivestreams.Publisher; - -/** - * Service provider. - */ -public interface PublisherFactory { - - Publisher createPublisher(TemplateInstance rendering); - -} diff --git a/independent-projects/qute/core/src/main/java/io/quarkus/qute/TemplateImpl.java b/independent-projects/qute/core/src/main/java/io/quarkus/qute/TemplateImpl.java index 5d500130d8c87..848c171148679 100644 --- a/independent-projects/qute/core/src/main/java/io/quarkus/qute/TemplateImpl.java +++ b/independent-projects/qute/core/src/main/java/io/quarkus/qute/TemplateImpl.java @@ -1,5 +1,6 @@ package io.quarkus.qute; +import io.smallrye.mutiny.Multi; import java.util.List; import java.util.Optional; import java.util.Set; @@ -9,7 +10,6 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.function.Consumer; -import org.reactivestreams.Publisher; class TemplateImpl implements Template { @@ -68,12 +68,15 @@ public String render() { } @Override - public Publisher publisher() { - PublisherFactory factory = engine.getPublisherFactory(); - if (factory == null) { - throw new UnsupportedOperationException(); - } - return factory.createPublisher(this); + public Multi createMulti() { + return Multi.createFrom().emitter(emitter -> consume(emitter::emit) + .whenComplete((r, f) -> { + if (f == null) { + emitter.complete(); + } else { + emitter.fail(f); + } + })); } @Override diff --git a/independent-projects/qute/core/src/main/java/io/quarkus/qute/TemplateInstance.java b/independent-projects/qute/core/src/main/java/io/quarkus/qute/TemplateInstance.java index ce950fb955b57..de39258923ff7 100644 --- a/independent-projects/qute/core/src/main/java/io/quarkus/qute/TemplateInstance.java +++ b/independent-projects/qute/core/src/main/java/io/quarkus/qute/TemplateInstance.java @@ -1,5 +1,6 @@ package io.quarkus.qute; +import io.smallrye.mutiny.Multi; import java.util.concurrent.CompletionStage; import java.util.function.Consumer; import org.reactivestreams.Publisher; @@ -79,8 +80,19 @@ public interface TemplateInstance { * * @return a publisher that can be used to consume chunks of the rendered template * @throws UnsupportedOperationException If no {@link PublisherFactory} service provider is found + * @deprecated Use {@link #createMulti()} instead */ - Publisher publisher(); + @Deprecated + default Publisher publisher() { + return createMulti(); + } + + /** + * Each subscription triggers rendering. + * + * @return a Multi that can be used to consume chunks of the rendered template + */ + Multi createMulti(); /** * Triggers rendering. diff --git a/independent-projects/qute/mutiny/src/test/java/com/github/mkouba/qute/mutiny/SimplePublisherTest.java b/independent-projects/qute/core/src/test/java/io/quarkus/qute/CreateMultiTest.java similarity index 55% rename from independent-projects/qute/mutiny/src/test/java/com/github/mkouba/qute/mutiny/SimplePublisherTest.java rename to independent-projects/qute/core/src/test/java/io/quarkus/qute/CreateMultiTest.java index 3c1f84cae107b..df8af520b6150 100644 --- a/independent-projects/qute/mutiny/src/test/java/com/github/mkouba/qute/mutiny/SimplePublisherTest.java +++ b/independent-projects/qute/core/src/test/java/io/quarkus/qute/CreateMultiTest.java @@ -1,44 +1,36 @@ -package com.github.mkouba.qute.mutiny; +package io.quarkus.qute; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.fail; -import io.quarkus.qute.Engine; -import io.quarkus.qute.Template; import io.smallrye.mutiny.Multi; import java.util.Arrays; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import java.util.function.Supplier; import org.junit.jupiter.api.Test; -import org.reactivestreams.Publisher; -public class SimplePublisherTest { +public class CreateMultiTest { @Test public void test() throws InterruptedException { Engine engine = Engine.builder().addDefaultSectionHelpers().addDefaultValueResolvers().build(); Template template = engine.parse("{#each}{it}{/}"); List data = Arrays.asList("foo", "foo", "alpha"); - Publisher publisher = template.instance().data(data).publisher(); + Multi multi = template.instance().data(data).createMulti(); - assertPublisher(() -> Multi.createFrom().publisher(publisher), "foofooalpha"); - assertPublisher(() -> Multi.createFrom().publisher(publisher) - .transform().byDroppingDuplicates(), "fooalpha"); - assertPublisher(() -> Multi.createFrom().publisher(publisher) - .transform().byTakingFirstItems(1), "foo"); + assertMulti(multi, "foofooalpha"); + assertMulti(multi.transform().byDroppingDuplicates(), "fooalpha"); + assertMulti(multi.transform().byTakingFirstItems(1), "foo"); } - private void assertPublisher(Supplier> test, String expected) throws InterruptedException { + private void assertMulti(Multi multi, String expected) throws InterruptedException { StringBuilder builder = new StringBuilder(); CountDownLatch latch = new CountDownLatch(1); - - Multi.createFrom().publisher(test.get()) + multi .subscribe().with( builder::append, latch::countDown); - if (latch.await(2, TimeUnit.SECONDS)) { assertEquals(expected, builder.toString()); } else { @@ -46,4 +38,4 @@ private void assertPublisher(Supplier> test, String expected) } } -} \ No newline at end of file +} diff --git a/independent-projects/qute/mutiny/pom.xml b/independent-projects/qute/mutiny/pom.xml deleted file mode 100644 index 330252d4a2759..0000000000000 --- a/independent-projects/qute/mutiny/pom.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - 4.0.0 - - - io.quarkus.qute - qute-parent - 999-SNAPSHOT - ../ - - - qute-mutiny - Qute - Mutiny - - - - io.quarkus.qute - qute-core - - - io.smallrye.reactive - mutiny - - - org.junit.jupiter - junit-jupiter - test - - - - - \ No newline at end of file diff --git a/independent-projects/qute/mutiny/src/main/java/io/quarkus/qute/mutiny/MutinyPublisherFactory.java b/independent-projects/qute/mutiny/src/main/java/io/quarkus/qute/mutiny/MutinyPublisherFactory.java deleted file mode 100644 index fbc5a90206dbf..0000000000000 --- a/independent-projects/qute/mutiny/src/main/java/io/quarkus/qute/mutiny/MutinyPublisherFactory.java +++ /dev/null @@ -1,22 +0,0 @@ -package io.quarkus.qute.mutiny; - -import io.quarkus.qute.PublisherFactory; -import io.quarkus.qute.TemplateInstance; -import io.smallrye.mutiny.Multi; -import org.reactivestreams.Publisher; - -public class MutinyPublisherFactory implements PublisherFactory { - - @Override - public Publisher createPublisher(TemplateInstance rendering) { - return Multi.createFrom().emitter(emitter -> rendering - .consume(emitter::emit) - .whenComplete((r, f) -> { - if (f == null) { - emitter.complete(); - } else { - emitter.fail(f); - } - })); - } -} diff --git a/independent-projects/qute/mutiny/src/main/resources/META-INF/services/io.quarkus.qute.PublisherFactory b/independent-projects/qute/mutiny/src/main/resources/META-INF/services/io.quarkus.qute.PublisherFactory deleted file mode 100644 index c0ceca44ac3ee..0000000000000 --- a/independent-projects/qute/mutiny/src/main/resources/META-INF/services/io.quarkus.qute.PublisherFactory +++ /dev/null @@ -1 +0,0 @@ -io.quarkus.qute.mutiny.MutinyPublisherFactory \ No newline at end of file diff --git a/independent-projects/qute/pom.xml b/independent-projects/qute/pom.xml index f986289fe0d59..520d60989868a 100644 --- a/independent-projects/qute/pom.xml +++ b/independent-projects/qute/pom.xml @@ -38,15 +38,13 @@ 5.6.2 1.0.4.Final 3.3.2.Final - 1.0.3 - 0.5.3 3.0.0-M5 1.6.8 + 0.5.4 core - mutiny generator @@ -70,11 +68,6 @@ qute-generator ${project.version} - - io.quarkus.qute - qute-rxjava - ${project.version} - org.jboss.logging jboss-logging @@ -85,15 +78,10 @@ gizmo ${version.gizmo} - - org.reactivestreams - reactive-streams - ${version.reactivestreams} - io.smallrye.reactive mutiny - ${version.mutiny} + ${version.smallrye-mutiny} diff --git a/integration-tests/qute/pom.xml b/integration-tests/qute/pom.xml index f3c722a298406..7d611e299acb2 100644 --- a/integration-tests/qute/pom.xml +++ b/integration-tests/qute/pom.xml @@ -19,6 +19,10 @@ io.quarkus quarkus-resteasy-qute + + io.quarkus + quarkus-vertx-web + diff --git a/integration-tests/qute/src/main/java/io/quarkus/it/qute/HelloRoutes.java b/integration-tests/qute/src/main/java/io/quarkus/it/qute/HelloRoutes.java new file mode 100644 index 0000000000000..b541a8cc9b0f0 --- /dev/null +++ b/integration-tests/qute/src/main/java/io/quarkus/it/qute/HelloRoutes.java @@ -0,0 +1,20 @@ +package io.quarkus.it.qute; + +import javax.inject.Inject; + +import io.quarkus.qute.Template; +import io.quarkus.vertx.web.Route; +import io.smallrye.mutiny.Multi; +import io.vertx.core.http.HttpServerRequest; + +public class HelloRoutes { + + @Inject + Template hello; + + @Route(produces = "text/html") + Multi helloRoute(HttpServerRequest request) { + return hello.data("name", request.getParam("name")).createMulti(); + } + +} diff --git a/integration-tests/qute/src/test/java/io/quarkus/it/qute/QuteTestCase.java b/integration-tests/qute/src/test/java/io/quarkus/it/qute/QuteTestCase.java index 93b4ccbc97eb2..1ca76db7acf95 100644 --- a/integration-tests/qute/src/test/java/io/quarkus/it/qute/QuteTestCase.java +++ b/integration-tests/qute/src/test/java/io/quarkus/it/qute/QuteTestCase.java @@ -2,22 +2,28 @@ import static javax.ws.rs.core.Response.Status.NOT_FOUND; import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.Matchers.is; import org.junit.jupiter.api.Test; import io.quarkus.test.junit.QuarkusTest; import io.restassured.RestAssured; +import io.restassured.http.ContentType; @QuarkusTest public class QuteTestCase { @Test public void testTemplate() throws InterruptedException { - RestAssured.when().get("/hello?name=Ciri").then() - .body(containsString("Hello Ciri!")); - RestAssured.when().get("/hello").then() + RestAssured.when().get("/hello?name=Ciri").then().body(containsString("Hello Ciri!")); + RestAssured.when().get("/hello").then().body(containsString("Hello world!")); + RestAssured.given().accept(ContentType.HTML).when().get("/hello-route") + .then() + .contentType(is(ContentType.HTML.toString())) .body(containsString("Hello world!")); - + RestAssured.given().accept(ContentType.HTML).when().get("/hello-route?name=Ciri").then() + .contentType(is(ContentType.HTML.toString())) + .body(containsString("Hello Ciri!")); } @Test