Skip to content

Commit

Permalink
[2.13] Backport several scenarios related to HTTP, SQL and Monitoring…
Browse files Browse the repository at this point in the history
… modules (#1021)

* Test Extended Architecture (XA) connection

Provides coverage for https://issues.redhat.com/browse/QUARKUS-2742

(cherry picked from commit ce15b26)

* Improve reactive rest client "process paths before sub resources" scenario (#995)

There is an issue in upstream (quarkusio/quarkus#29821) that
only happens under some RestClient definition hierarchy.

This commit reproduces the problem in Quarkus 2.12 and earlier versions

(cherry picked from commit 2350b46)

* New Scenario: RequestScope custom context was removed after `javax.enterprise` event propagation

When firing an async CDI Event, the requestScope context from the emitter briefly exists for the observer
and is then terminated. This commit is a reproducer of this scenario that happens on Quarkus 2.13.0.Final

(cherry picked from commit ef3eed6)

* gRPC and SSE coverage for OpenTelemetry

(cherry picked from commit f327c60)

* Add coverage to eventbus '@ConsumeEvent' annotation

(cherry picked from commit 7da0d4b)

* Drop duplicated definition of quarkus-opentelemetry

(cherry picked from commit b0cba7f)

* OutboundSseEvent is not correctly serialized

(cherry picked from commit 99b5eb1)

* Check, that dev-mode is omitted on projects with pom packaging

Required for QUARKUS-2757

(cherry picked from commit 4fd38c7)

* Refactoring of QUARKUS-2748: adding http test and improving error messages

(cherry picked from commit 6563431)

* Add test for security annotations in rest-data-panache (#994)

Quarkus extensions based on `rest-data-panache` support propagation of
security annotations into generated JAX-RS resources.
These tests provide coverage of this feature for extensions:
- `quarkus-hibernate-orm-rest-data-panache`
- `quarkus-spring-data-rest`

See also related test plan:
- https://github.com/quarkus-qe/quarkus-test-plans/blob/main/QUARKUS-2788.md

(cherry picked from commit 3f7a4c8)

* Add transaction-API classic scenario

(cherry picked from commit 509d491)

* Cover Vert.X-specific metrics. (#1019)

Add new module, which uses Vert.X-based HTTP server
Verify, that it works, and that it creates all required metrics
Required for https://issues.redhat.com/browse/QUARKUS-2829

(cherry picked from commit 818837f)

* Add missing opentelemetry exporter to Narayana scenario

---------

Co-authored-by: Fedor Dudinskiy <[email protected]>
Co-authored-by: Rostislav Svoboda <[email protected]>
Co-authored-by: Josef Smrcka <[email protected]>
  • Loading branch information
4 people authored Feb 1, 2023
1 parent 537a385 commit fa5a391
Show file tree
Hide file tree
Showing 107 changed files with 3,312 additions and 84 deletions.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,13 @@ Exclusions: XML test. Reason: https://quarkus.io/blog/resteasy-reactive/#what-ja
Verifies HTTP endpoints validation using `quarkus-hibernate-validator` works correctly in Resteasy Classic and Resteasy Reactive.
This module will setup a simple endpoint and will validate the right message format is set when there are validation errors.

### `http/vertx`
Verifies that you can deploy a simple Vert.X-based HTTP endpoint to OpenShift, access it and retrieve metrics for it.
It also verifies multiple deployment strategies like:
- Serverless
- Using OpenShift quarkus extension
- Using OpenShift quarkus extension and Docker Build strategy

#### Additions
* *@Deprecated* annotation has been added for test regression purposes to ensure `java.lang` annotations are allowed for resources
* Resource with multipart body support, provided parts are text, image and binary data, charset checked with `us-ascii` and `utf-8`
Expand Down Expand Up @@ -538,6 +545,13 @@ Base application is reduced to two REST resources:
Tests cover the supported functionality of `rest-data-panache`: CRUD operations, `json` and `hal+json` data types,
invalid input, filtering, sorting, pagination.

### `sql-db/narayana-transactions`

Verifies Quarkus transaction programmatic API.
Base application contains REST resource `TransferResource` and three main services: `TransferTransactionService`, `TransferWithdrawalService`
and `TransferTopUpService` which implement various bank transactions. The main scenario is implemented in `TransactionGeneralUsageIT`
and checks whether transactions and rollbacks always done in full.

### `security/basic`

Verifies the simplest way of doing authn/authz.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,4 @@ pl-container-request-filter.enabled=false
quarkus.index-dependency.resteasy-multipart.group-id=org.jboss.resteasy
quarkus.index-dependency.resteasy-multipart.artifact-id=resteasy-multipart-provider

quarkus.qe.test.value=42
qe.test.value=42
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package io.quarkus.ts.http.advanced.reactive;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.io.IOException;
import java.nio.file.Files;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.jboss.logging.Logger;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;

import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.DomElement;
import com.gargoylesoftware.htmlunit.html.HtmlPage;

import io.quarkus.test.bootstrap.RestService;
import io.quarkus.test.services.URILike;
import io.quarkus.test.utils.AwaitilityUtils;

public abstract class AbstractDevModeIT {
private static final Logger LOG = Logger.getLogger(AbstractDevModeIT.class);
protected static final String PROPERTY = "qe.test.value";
protected WebClient webClient;

@BeforeEach
void setUp() {
webClient = new WebClient();

webClient.getOptions().setRedirectEnabled(true); //required for the test case
//The execution breaks without the option below
webClient.getOptions().setWebSocketEnabled(false);

//make sure, that the cache doesn't affect us
webClient.getCookieManager().clearCookies();
webClient.getCookieManager().setCookiesEnabled(false);
webClient.getCache().clear();
webClient.getCache().setMaxSize(0);

//disable everything, that we don't need
webClient.getOptions().setDownloadImages(false);
webClient.getOptions().setGeolocationEnabled(false);
webClient.getOptions().setAppletEnabled(false);
webClient.getOptions().setCssEnabled(false);
}

@Test
@Disabled("https://github.com/quarkusio/quarkus/issues/30511")
public void uiChange() throws IOException {
RestService app = getApp();
URILike uri = getUri();

HtmlPage before = webClient.getPage(uri.withPath("/q/dev/io.quarkus.quarkus-vertx-http/config").toString());
QuarkusUIField field = new QuarkusUIField(before.getElementById(PROPERTY));
assertEquals("42", field.getValue(), "Wrong initial value shown in UI!");
assertEquals("42", app.getProperty(PROPERTY, ""), "Properties contain wrong initial value!");

field.setValue("23");
HtmlPage saved = field.getSaveButton().click();
QuarkusUIField updated = new QuarkusUIField(saved.getElementById(PROPERTY));
assertEquals("23", updated.getValue(), "The value was not updated in UI");

AwaitilityUtils.untilIsTrue(() -> app.getLogs().stream().anyMatch(log -> log.contains("File change detected")));
try (Stream<String> lines = Files
.lines(app.getServiceFolder().resolve("src/main/resources/application.properties"))) {
List<String> properties = lines
.filter(line -> line.contains(PROPERTY))
.collect(Collectors.toList());
if (properties.size() != 1) {
LOG.warn("There should be only one property with name " + PROPERTY + ", but found these " + properties);
}
}
assertEquals("23", app.getProperty(PROPERTY, ""), "Wrong value was read from application properties");
}

protected abstract URILike getUri();

protected abstract RestService getApp();

@AfterEach
void tearDown() {
webClient.close();
}

protected class QuarkusUIField {
private final DomElement element;

public QuarkusUIField(DomElement element) {
this.element = element;
}

public String getValue() {
return element.getAttribute("value");
}

public void setValue(String newValue) {
element.setAttribute("value", newValue);
}

public DomElement getSaveButton() {
for (DomElement sibling : element.getParentNode().getDomElementDescendants()) {
if (sibling.getAttribute("class").equals("input-group-text formInputButton")) {
return sibling;
}
}
throw new IllegalStateException("Save button was not found!");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package io.quarkus.ts.http.advanced.reactive;

import io.quarkus.test.bootstrap.DevModeQuarkusService;
import io.quarkus.test.bootstrap.Protocol;
import io.quarkus.test.bootstrap.RestService;
import io.quarkus.test.scenarios.QuarkusScenario;
import io.quarkus.test.services.DevModeQuarkusApplication;
import io.quarkus.test.services.URILike;

@QuarkusScenario
public class DevModeHttpIT extends AbstractDevModeIT {

@DevModeQuarkusApplication(ssl = false)
static RestService app = new DevModeQuarkusService()
.withProperty("quarkus.oidc.enabled", "false")
.withProperty("quarkus.keycloak.policy-enforcer.enable", "false")
.withProperty("quarkus.keycloak.devservices.enabled", "false");

@Override
protected URILike getUri() {
return app.getURI(Protocol.HTTP);
}

@Override
protected RestService getApp() {
return app;
}
}
Original file line number Diff line number Diff line change
@@ -1,109 +1,37 @@
package io.quarkus.ts.http.advanced.reactive;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.io.IOException;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;

import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.DomElement;
import com.gargoylesoftware.htmlunit.html.HtmlPage;

import io.quarkus.test.bootstrap.DevModeQuarkusService;
import io.quarkus.test.bootstrap.Protocol;
import io.quarkus.test.bootstrap.RestService;
import io.quarkus.test.scenarios.QuarkusScenario;
import io.quarkus.test.scenarios.annotations.DisabledOnQuarkusVersion;
import io.quarkus.test.services.DevModeQuarkusApplication;
import io.quarkus.test.services.URILike;
import io.quarkus.test.utils.AwaitilityUtils;

@QuarkusScenario
//TODO https://github.com/quarkusio/quarkus/issues/30503
@DisabledOnQuarkusVersion(version = "2\\.13\\.[0-7].*", reason = "Missing patch from upstream")
public class DevModeHttpsIT {
private static final String PROPERTY = "quarkus.qe.test.value";
public class DevModeHttpsIT extends AbstractDevModeIT {

@DevModeQuarkusApplication(ssl = true)
static RestService app = new DevModeQuarkusService()
.withProperty("quarkus.oidc.enabled", "false")
.withProperty("quarkus.keycloak.policy-enforcer.enable", "false")
.withProperty("quarkus.keycloak.devservices.enabled", "false");

private WebClient webClient;

@BeforeEach
void setUp() {
webClient = new WebClient();

webClient.getOptions().setRedirectEnabled(true); //required for the test case
//The execution breaks without the two options below
super.setUp();
//The execution breaks without the option below
webClient.getOptions().setUseInsecureSSL(true);
webClient.getOptions().setWebSocketEnabled(false);

//make sure, that the cache doesn't affect us
webClient.getCookieManager().clearCookies();
webClient.getCookieManager().setCookiesEnabled(false);
webClient.getCache().clear();
webClient.getCache().setMaxSize(0);

//disable everything, that we don't need
webClient.getOptions().setDownloadImages(false);
webClient.getOptions().setGeolocationEnabled(false);
webClient.getOptions().setAppletEnabled(false);
webClient.getOptions().setCssEnabled(false);
}

@AfterEach
void tearDown() {
webClient.close();
}

@Tag("QUARKUS-2748")
@Test
public void uiChange() throws IOException {
URILike uri = app.getURI(Protocol.HTTPS);

HtmlPage before = webClient.getPage(uri.withPath("/q/dev/io.quarkus.quarkus-vertx-http/config").toString());
QuarkusUIField field = new QuarkusUIField(before.getElementById(PROPERTY));
assertEquals("42", field.getValue());
assertEquals("42", app.getProperty(PROPERTY, ""));

field.setValue("23");
HtmlPage saved = field.getSaveButton().click();
QuarkusUIField updated = new QuarkusUIField(saved.getElementById(PROPERTY));
assertEquals("23", updated.getValue());

AwaitilityUtils.untilIsTrue(() -> app.getLogs().stream().anyMatch(log -> log.contains("File change detected")));
assertEquals("23", app.getProperty(PROPERTY, ""));
}
}

class QuarkusUIField {
private final DomElement element;

QuarkusUIField(DomElement element) {
this.element = element;
}

public String getValue() {
return element.getAttribute("value");
}

public void setValue(String newValue) {
element.setAttribute("value", newValue);
@Override
protected URILike getUri() {
return app.getURI(Protocol.HTTPS);
}

public DomElement getSaveButton() {
for (DomElement sibling : element.getParentNode().getDomElementDescendants()) {
if (sibling.getAttribute("class").equals("input-group-text formInputButton")) {
return sibling;
}
}
throw new IllegalStateException("Save button was not found!");
@Override
protected RestService getApp() {
return app;
}
}
38 changes: 38 additions & 0 deletions http/vertx/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>io.quarkus.ts.qe</groupId>
<artifactId>parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<artifactId>vertx</artifactId>
<packaging>jar</packaging>
<name>Quarkus QE TS: HTTP: Vert.X</name>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-reactive-jackson</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-vertx</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-micrometer-registry-prometheus</artifactId>
</dependency>
</dependencies>
<profiles>
<profile>
<id>deploy-to-openshift-using-extension</id>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-openshift</artifactId>
</dependency>
</dependencies>
</profile>
</profiles>
</project>
14 changes: 14 additions & 0 deletions http/vertx/src/main/java/io/quarkus/ts/vertx/Hello.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package io.quarkus.ts.vertx;

public class Hello {

private final String content;

public Hello(String content) {
this.content = content;
}

public String getContent() {
return content;
}
}
33 changes: 33 additions & 0 deletions http/vertx/src/main/java/io/quarkus/ts/vertx/HelloResource.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package io.quarkus.ts.vertx;

import javax.inject.Inject;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;

import io.smallrye.mutiny.Uni;
import io.vertx.mutiny.core.Vertx;
import io.vertx.mutiny.core.buffer.Buffer;

@Path("/hello")
public class HelloResource {
private final Vertx vertx;

@Inject
public HelloResource(Vertx vertx) {
this.vertx = vertx;
}

@GET
@Produces(MediaType.APPLICATION_JSON)
public Uni<Hello> getMessage(@QueryParam("name") @DefaultValue("World") String name) {
return vertx.fileSystem()
.readFile("message.template")
.map(Buffer::toString)
.map(string -> String.format(string, name).trim())
.map(Hello::new);
}
}
6 changes: 6 additions & 0 deletions http/vertx/src/main/resources/application.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
quarkus.application.name=test-http
quarkus.native.resources.includes=message.template
%ServerlessExtensionOpenShiftHttpMinimumIT.quarkus.kubernetes.deployment-target=knative
%ServerlessExtensionOpenShiftHttpMinimumIT.quarkus.container-image.registry=image-registry.openshift-image-registry.svc:5000
%ServerlessExtensionDockerBuildStrategyOpenShiftHttpMinimumIT.quarkus.kubernetes.deployment-target=knative
%ServerlessExtensionDockerBuildStrategyOpenShiftHttpMinimumIT.quarkus.container-image.registry=image-registry.openshift-image-registry.svc:5000
1 change: 1 addition & 0 deletions http/vertx/src/main/resources/message.template
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Hello, %s!
Loading

0 comments on commit fa5a391

Please sign in to comment.