Skip to content

Commit

Permalink
Merge pull request #37115 from gsmet/3.5.2-backports-3
Browse files Browse the repository at this point in the history
3.5.2 backports 3
  • Loading branch information
gsmet committed Nov 16, 2023
2 parents eeba2c3 + 87d5728 commit 1f3a6d9
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 41 deletions.
12 changes: 12 additions & 0 deletions bom/application/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5236,6 +5236,7 @@
</exclusions>
</dependency>
<dependency>
<!-- this artifact has been relocated to com.mysql:mysql-connector-j -->
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-jdbc.version}</version>
Expand All @@ -5246,6 +5247,17 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>${mysql-jdbc.version}</version>
<exclusions>
<exclusion>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derbyclient</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.quarkus.cache.runtime;

import java.time.Duration;
import java.util.concurrent.Executor;
import java.util.function.Function;
import java.util.function.Supplier;

Expand All @@ -16,6 +17,10 @@
import io.smallrye.mutiny.Multi;
import io.smallrye.mutiny.TimeoutException;
import io.smallrye.mutiny.Uni;
import io.vertx.core.Context;
import io.vertx.core.Handler;
import io.vertx.core.Vertx;
import io.vertx.core.impl.ContextInternal;

@CacheResult(cacheName = "") // The `cacheName` attribute is @Nonbinding.
@Interceptor
Expand Down Expand Up @@ -53,6 +58,7 @@ public Object intercept(InvocationContext invocationContext) throws Throwable {
try {
ReturnType returnType = determineReturnType(invocationContext.getMethod().getReturnType());
if (returnType != ReturnType.NonAsync) {
Context context = Vertx.currentContext();
Uni<Object> cacheValue = cache.getAsync(key, new Function<Object, Uni<Object>>() {
@SuppressWarnings("unchecked")
@Override
Expand All @@ -65,11 +71,54 @@ public Uni<Object> apply(Object key) {
throw new CacheException(e);
}
}
}).emitOn(new Executor() {
// We need make sure we go back to the original context when the cache value is computed.
// Otherwise, we would always emit on the context having computed the value, which could
// break the duplicated context isolation.
@Override
public void execute(Runnable command) {
Context ctx = Vertx.currentContext();
if (context == null) {
// We didn't capture a context
if (ctx == null) {
// We are not on a context => we can execute immediately.
command.run();
} else {
// We are on a context.
// We cannot continue on the current context as we may share a duplicated context.
// We need a new one. Note that duplicate() does not duplicate the duplicated context,
// but the root context.
((ContextInternal) ctx).duplicate()
.runOnContext(new Handler<Void>() {
@Override
public void handle(Void ignored) {
command.run();
}
});
}
} else {
// We captured a context.
if (ctx == context) {
// We are on the same context => we can execute immediately
command.run();
} else {
// 1) We are not on a context (ctx == null) => we need to switch to the captured context.
// 2) We are on a different context (ctx != null) => we need to switch to the captured context.
context.runOnContext(new Handler<Void>() {
@Override
public void handle(Void ignored) {
command.run();
}
});
}
}
}
});

if (binding.lockTimeout() <= 0) {
return createAsyncResult(cacheValue, returnType);
}
// IMPORTANT: The item/failure are emitted on the captured context.
cacheValue = cacheValue.ifNoItem().after(Duration.ofMillis(binding.lockTimeout()))
.recoverWithUni(new Supplier<Uni<?>>() {
@Override
Expand Down
4 changes: 2 additions & 2 deletions extensions/devservices/mysql/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
</dependencies>
<build>
Expand Down
6 changes: 3 additions & 3 deletions extensions/jdbc/jdbc-mysql/runtime/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
<dependency>
<groupId>org.graalvm.sdk</groupId>
Expand All @@ -45,7 +45,7 @@
<artifactId>quarkus-extension-maven-plugin</artifactId>
<configuration>
<parentFirstArtifacts>
<parentFirstArtifact>mysql:mysql-connector-java</parentFirstArtifact>
<parentFirstArtifact>com.mysql:mysql-connector-j</parentFirstArtifact>
</parentFirstArtifacts>
</configuration>
</plugin>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package io.quarkus.rest.client.reactive.runtime;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
Expand All @@ -21,10 +22,10 @@
import org.eclipse.microprofile.rest.client.ext.QueryParamStyle;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
import org.jboss.resteasy.reactive.client.api.QuarkusRestClientProperties;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.mockito.Mockito;

import io.netty.handler.codec.http.multipart.HttpPostRequestEncoder;
Expand All @@ -38,26 +39,47 @@ public class RestClientCDIDelegateBuilderTest {
private static final String TRUSTSTORE_PASSWORD = "truststorePassword";
private static final String KEYSTORE_PASSWORD = "keystorePassword";

@TempDir
static File tempDir;
private static File truststoreFile;
private static File keystoreFile;
private static Path truststorePath;
private static Path keystorePath;
private static Config createdConfig;

@BeforeAll
public static void beforeAll() throws IOException, KeyStoreException, CertificateException, NoSuchAlgorithmException {
// prepare keystore and truststore

truststoreFile = new File(tempDir, "truststore.jks");
keystoreFile = new File(tempDir, "keystore.jks");
truststorePath = Files.createTempFile("truststore", ".jks");

KeyStore truststore = KeyStore.getInstance("JKS");
truststore.load(null, TRUSTSTORE_PASSWORD.toCharArray());
truststore.store(new FileOutputStream(truststoreFile), TRUSTSTORE_PASSWORD.toCharArray());
try (OutputStream truststoreOs = Files.newOutputStream(truststorePath)) {
KeyStore truststore = KeyStore.getInstance("JKS");
truststore.load(null, TRUSTSTORE_PASSWORD.toCharArray());
truststore.store(truststoreOs, TRUSTSTORE_PASSWORD.toCharArray());
}

keystorePath = Files.createTempFile("keystore", ".jks");

KeyStore keystore = KeyStore.getInstance("JKS");
keystore.load(null, KEYSTORE_PASSWORD.toCharArray());
keystore.store(new FileOutputStream(keystoreFile), KEYSTORE_PASSWORD.toCharArray());
try (OutputStream keystoreOs = Files.newOutputStream(keystorePath)) {
KeyStore keystore = KeyStore.getInstance("JKS");
keystore.load(null, KEYSTORE_PASSWORD.toCharArray());
keystore.store(keystoreOs, KEYSTORE_PASSWORD.toCharArray());
}
}

@AfterAll
public static void afterAll() {
if (truststorePath != null) {
try {
Files.deleteIfExists(truststorePath);
} catch (IOException e) {
// ignore it
}
}
if (keystorePath != null) {
try {
Files.deleteIfExists(keystorePath);
} catch (IOException e) {
// ignore it
}
}
}

@AfterEach
Expand Down Expand Up @@ -183,10 +205,10 @@ private static RestClientsConfig createSampleConfigRoot() {
.of("io.quarkus.rest.client.reactive.runtime.RestClientCDIDelegateBuilderTest$MyResponseFilter2");
configRoot.queryParamStyle = Optional.of(QueryParamStyle.MULTI_PAIRS);

configRoot.trustStore = Optional.of(truststoreFile.getAbsolutePath());
configRoot.trustStore = Optional.of(truststorePath.toAbsolutePath().toString());
configRoot.trustStorePassword = Optional.of("truststorePassword");
configRoot.trustStoreType = Optional.of("JKS");
configRoot.keyStore = Optional.of(keystoreFile.getAbsolutePath());
configRoot.keyStore = Optional.of(keystorePath.toAbsolutePath().toString());
configRoot.keyStorePassword = Optional.of("keystorePassword");
configRoot.keyStoreType = Optional.of("JKS");

Expand Down Expand Up @@ -222,10 +244,10 @@ private static RestClientConfig createSampleClientConfig() {
.of("io.quarkus.rest.client.reactive.runtime.RestClientCDIDelegateBuilderTest$MyResponseFilter1");
clientConfig.queryParamStyle = Optional.of(QueryParamStyle.COMMA_SEPARATED);

clientConfig.trustStore = Optional.of(truststoreFile.getAbsolutePath());
clientConfig.trustStore = Optional.of(truststorePath.toAbsolutePath().toString());
clientConfig.trustStorePassword = Optional.of("truststorePassword");
clientConfig.trustStoreType = Optional.of("JKS");
clientConfig.keyStore = Optional.of(keystoreFile.getAbsolutePath());
clientConfig.keyStore = Optional.of(keystorePath.toAbsolutePath().toString());
clientConfig.keyStorePassword = Optional.of("keystorePassword");
clientConfig.keyStoreType = Optional.of("JKS");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.test.QuarkusUnitTest;
Expand All @@ -29,6 +31,7 @@
/**
* Reproduce CVE-2023-44487.
*/
@DisabledOnOs(OS.WINDOWS)
public class Http2RSTFloodProtectionTest {

@TestHTTPResource(value = "/ping", ssl = true)
Expand Down Expand Up @@ -81,7 +84,7 @@ void run(HttpClient client, int port, boolean plain) throws InterruptedException
.compose(HttpClientRequest::send);
}

for (int i = 0; i < 250; i++) { // must be higher thant the NEtty limit (200 / 30s)
for (int i = 0; i < 250; i++) { // must be higher than the Netty limit (200 / 30s)
client.request(GET, port, "localhost", "/ping")
.onSuccess(req -> req.end().onComplete(v -> req.reset()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,25 +66,36 @@ void testConsoleQuestion_no() throws IOException {

@Test
void testConsoleQuestion_promptTimeout() throws IOException {
System.setProperty("quarkus.analytics.prompt.timeout", "0");
assertFalse(fileLocations.getLocalConfigFile().toFile().exists());
service.buildAnalyticsUserInput((String prompt) -> {
assertEquals(ACCEPTANCE_PROMPT, prompt);
return "n";
});
assertFalse(fileLocations.getLocalConfigFile().toFile().exists());
System.clearProperty("quarkus.analytics.prompt.timeout");
try {
System.setProperty("quarkus.analytics.prompt.timeout", "0");
assertFalse(fileLocations.getLocalConfigFile().toFile().exists());
service.buildAnalyticsUserInput((String prompt) -> {
assertEquals(ACCEPTANCE_PROMPT, prompt);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "n";
});
assertFalse(fileLocations.getLocalConfigFile().toFile().exists());
} finally {
System.clearProperty("quarkus.analytics.prompt.timeout");
}
}

@Test
void testConsoleQuestion_AnalyticsDisabled() throws IOException {
System.setProperty("quarkus.analytics.disabled", "true");
assertFalse(fileLocations.getLocalConfigFile().toFile().exists());
service.buildAnalyticsUserInput((String prompt) -> {
fail("Prompt should be disabled");
return "n";
});
assertFalse(fileLocations.getLocalConfigFile().toFile().exists());
System.clearProperty("quarkus.analytics.disabled");
try {
System.setProperty("quarkus.analytics.disabled", "true");
assertFalse(fileLocations.getLocalConfigFile().toFile().exists());
service.buildAnalyticsUserInput((String prompt) -> {
fail("Prompt should be disabled");
return "n";
});
assertFalse(fileLocations.getLocalConfigFile().toFile().exists());
} finally {
System.clearProperty("quarkus.analytics.disabled");
}
}
}

0 comments on commit 1f3a6d9

Please sign in to comment.