label();
/**
* The amount of time to wait when initially establishing a connection before giving up and timing out.
*
* Specify `0` to wait indefinitely.
*/
- @ConfigItem(defaultValue = "10S")
- public Duration connectionTimeout;
+ @WithDefault("10S")
+ @WithConverter(DurationConverter.class)
+ Duration connectionTimeout();
/**
* The amount of time to wait for a read on a socket before an exception is thrown.
*
* Specify `0` to wait indefinitely.
*/
- @ConfigItem(defaultValue = "60S")
- public Duration readTimeout;
+ @WithDefault("60S")
+ @WithConverter(DurationConverter.class)
+ Duration readTimeout();
/**
* The username to be used if the Config Server has BASIC Auth enabled
*/
- @ConfigItem
- public Optional username;
+ Optional username();
/**
* The password to be used if the Config Server has BASIC Auth enabled
*/
- @ConfigItem
- public Optional password;
+ Optional password();
/**
* TrustStore to be used containing the SSL certificate used by the Config server
* Can be either a classpath resource or a file system path
*/
- @ConfigItem
- public Optional trustStore;
+ @WithConverter(PathConverter.class)
+ Optional trustStore();
/**
* Password of TrustStore to be used containing the SSL certificate used by the Config server
*/
- @ConfigItem
- public Optional trustStorePassword;
+ Optional trustStorePassword();
/**
* KeyStore to be used containing the SSL certificate for authentication with the Config server
* Can be either a classpath resource or a file system path
*/
- @ConfigItem
- public Optional keyStore;
+ @WithConverter(PathConverter.class)
+ Optional keyStore();
/**
* Password of KeyStore to be used containing the SSL certificate for authentication with the Config server
*/
- @ConfigItem
- public Optional keyStorePassword;
+ Optional keyStorePassword();
/**
* Password to recover key from KeyStore for SSL client authentication with the Config server
* If no value is provided, the key-store-password will be used
*/
- @ConfigItem
- public Optional keyPassword;
+ Optional keyPassword();
/**
* When using HTTPS and no keyStore has been specified, whether to trust all certificates
*/
- @ConfigItem(defaultValue = "false")
- public boolean trustCerts;
+ @WithDefault("${quarkus.tls.trust-all:false}")
+ boolean trustCerts();
/**
* Custom headers to pass the Spring Cloud Config Server when performing the HTTP request
*/
- @ConfigItem
- public Map headers;
+ Map headers();
- public boolean usernameAndPasswordSet() {
- return username.isPresent() && password.isPresent();
+ /** */
+ default boolean usernameAndPasswordSet() {
+ return username().isPresent() && password().isPresent();
}
}
diff --git a/extensions/spring-cloud-config-client/runtime/src/main/java/io/quarkus/spring/cloud/config/client/runtime/SpringCloudConfigClientConfigBuilder.java b/extensions/spring-cloud-config-client/runtime/src/main/java/io/quarkus/spring/cloud/config/client/runtime/SpringCloudConfigClientConfigBuilder.java
new file mode 100644
index 0000000000000..feef047c9fb7a
--- /dev/null
+++ b/extensions/spring-cloud-config-client/runtime/src/main/java/io/quarkus/spring/cloud/config/client/runtime/SpringCloudConfigClientConfigBuilder.java
@@ -0,0 +1,11 @@
+package io.quarkus.spring.cloud.config.client.runtime;
+
+import io.quarkus.runtime.configuration.ConfigBuilder;
+import io.smallrye.config.SmallRyeConfigBuilder;
+
+public class SpringCloudConfigClientConfigBuilder implements ConfigBuilder {
+ @Override
+ public SmallRyeConfigBuilder configBuilder(final SmallRyeConfigBuilder builder) {
+ return builder.withSources(new SpringCloudConfigClientConfigSourceFactory());
+ }
+}
diff --git a/extensions/spring-cloud-config-client/runtime/src/main/java/io/quarkus/spring/cloud/config/client/runtime/SpringCloudConfigClientConfigSourceFactory.java b/extensions/spring-cloud-config-client/runtime/src/main/java/io/quarkus/spring/cloud/config/client/runtime/SpringCloudConfigClientConfigSourceFactory.java
new file mode 100644
index 0000000000000..e3c3e7a85f394
--- /dev/null
+++ b/extensions/spring-cloud-config-client/runtime/src/main/java/io/quarkus/spring/cloud/config/client/runtime/SpringCloudConfigClientConfigSourceFactory.java
@@ -0,0 +1,107 @@
+package io.quarkus.spring.cloud.config.client.runtime;
+
+import static java.util.Collections.emptyList;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.microprofile.config.spi.ConfigSource;
+import org.jboss.logging.Logger;
+
+import io.quarkus.spring.cloud.config.client.runtime.Response.PropertySource;
+import io.smallrye.config.ConfigSourceContext;
+import io.smallrye.config.ConfigSourceFactory.ConfigurableConfigSourceFactory;
+import io.smallrye.config.ConfigValue;
+import io.smallrye.config.common.MapBackedConfigSource;
+
+public class SpringCloudConfigClientConfigSourceFactory
+ implements ConfigurableConfigSourceFactory {
+ private static final Logger log = Logger.getLogger(SpringCloudConfigClientConfigSourceFactory.class);
+
+ @Override
+ public Iterable getConfigSources(final ConfigSourceContext context,
+ final SpringCloudConfigClientConfig config) {
+ List sources = new ArrayList<>();
+
+ if (!config.enabled()) {
+ log.debug(
+ "No attempt will be made to obtain configuration from the Spring Cloud Config Server because the functionality has been disabled via configuration");
+ return sources;
+ }
+
+ ConfigValue applicationName = context.getValue("quarkus.application.name");
+ if (applicationName == null || applicationName.getValue() == null) {
+ log.warn(
+ "No attempt will be made to obtain configuration from the Spring Cloud Config Server because the application name has not been set. Consider setting it via 'quarkus.application.name'");
+ return sources;
+ }
+
+ boolean connectionTimeoutIsGreaterThanZero = !config.connectionTimeout().isNegative()
+ && !config.connectionTimeout().isZero();
+ boolean readTimeoutIsGreaterThanZero = !config.readTimeout().isNegative() && !config.readTimeout().isZero();
+
+ VertxSpringCloudConfigGateway client = new VertxSpringCloudConfigGateway(config);
+ try {
+ List responses = new ArrayList<>();
+ for (String profile : context.getProfiles()) {
+ Response response;
+ if (connectionTimeoutIsGreaterThanZero || readTimeoutIsGreaterThanZero) {
+ response = client.exchange(applicationName.getValue(), profile).await()
+ .atMost(config.connectionTimeout().plus(config.readTimeout().multipliedBy(2)));
+ } else {
+ response = client.exchange(applicationName.getValue(), profile).await().indefinitely();
+ }
+
+ if (response.getProfiles().contains(profile)) {
+ responses.add(response);
+ }
+ }
+
+ int ordinal = 450;
+ // Profiles are looked from the highest ordinal to lowest, so we reverse the collection to build the source list
+ Collections.reverse(responses);
+ for (Response response : responses) {
+ List propertySources = response.getPropertySources();
+ // Same reverse rule here
+ Collections.reverse(propertySources);
+
+ for (PropertySource propertySource : propertySources) {
+ sources.add(SpringCloudPropertySource.from(propertySource, response.getProfiles(), ordinal++));
+ }
+ }
+
+ return sources;
+
+ } catch (Exception e) {
+ final String errorMessage = "Unable to obtain configuration from Spring Cloud Config Server at " + config.url();
+ if (config.failFast()) {
+ throw new RuntimeException(errorMessage, e);
+ } else {
+ log.error(errorMessage, e);
+ return emptyList();
+ }
+ } finally {
+ client.close();
+ }
+ }
+
+ private static class SpringCloudPropertySource extends MapBackedConfigSource {
+ private SpringCloudPropertySource(final String name, final Map propertyMap, final int defaultOrdinal) {
+ super(name, propertyMap, defaultOrdinal);
+ }
+
+ static SpringCloudPropertySource from(PropertySource propertySource, List profiles, int ordinal) {
+ Map values = new HashMap<>();
+ Map source = propertySource.getSource();
+ for (String profile : profiles) {
+ for (Map.Entry entry : source.entrySet()) {
+ values.put("%" + profile + "." + entry.getKey(), entry.getValue());
+ }
+ }
+ return new SpringCloudPropertySource(propertySource.getName(), values, ordinal);
+ }
+ }
+}
diff --git a/extensions/spring-cloud-config-client/runtime/src/main/java/io/quarkus/spring/cloud/config/client/runtime/SpringCloudConfigClientRecorder.java b/extensions/spring-cloud-config-client/runtime/src/main/java/io/quarkus/spring/cloud/config/client/runtime/SpringCloudConfigClientRecorder.java
deleted file mode 100644
index 7cc4cebd1b46a..0000000000000
--- a/extensions/spring-cloud-config-client/runtime/src/main/java/io/quarkus/spring/cloud/config/client/runtime/SpringCloudConfigClientRecorder.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package io.quarkus.spring.cloud.config.client.runtime;
-
-import java.util.Collections;
-
-import org.eclipse.microprofile.config.spi.ConfigSource;
-import org.eclipse.microprofile.config.spi.ConfigSourceProvider;
-import org.jboss.logging.Logger;
-
-import io.quarkus.runtime.ApplicationConfig;
-import io.quarkus.runtime.RuntimeValue;
-import io.quarkus.runtime.TlsConfig;
-import io.quarkus.runtime.annotations.Recorder;
-import io.quarkus.runtime.configuration.ProfileManager;
-
-@Recorder
-public class SpringCloudConfigClientRecorder {
-
- private static final Logger log = Logger.getLogger(SpringCloudConfigClientRecorder.class);
-
- public RuntimeValue create(SpringCloudConfigClientConfig springCloudConfigClientConfig,
- ApplicationConfig applicationConfig, TlsConfig tlsConfig) {
- if (!springCloudConfigClientConfig.enabled) {
- log.debug(
- "No attempt will be made to obtain configuration from the Spring Cloud Config Server because the functionality has been disabled via configuration");
- return emptyRuntimeValue();
- }
-
- if (!applicationConfig.name.isPresent()) {
- log.warn(
- "No attempt will be made to obtain configuration from the Spring Cloud Config Server because the application name has not been set. Consider setting it via 'quarkus.application.name'");
- return emptyRuntimeValue();
- }
-
- return new RuntimeValue<>(new SpringCloudConfigServerClientConfigSourceProvider(
- springCloudConfigClientConfig, applicationConfig.name.get(), ProfileManager.getActiveProfile(), tlsConfig));
- }
-
- private RuntimeValue emptyRuntimeValue() {
- return new RuntimeValue<>(new EmptyConfigSourceProvider());
- }
-
- private static class EmptyConfigSourceProvider implements ConfigSourceProvider {
-
- @Override
- public Iterable getConfigSources(ClassLoader forClassLoader) {
- return Collections.emptyList();
- }
- }
-}
diff --git a/extensions/spring-cloud-config-client/runtime/src/main/java/io/quarkus/spring/cloud/config/client/runtime/SpringCloudConfigServerClientConfigSourceProvider.java b/extensions/spring-cloud-config-client/runtime/src/main/java/io/quarkus/spring/cloud/config/client/runtime/SpringCloudConfigServerClientConfigSourceProvider.java
deleted file mode 100644
index 6381d50b9d48c..0000000000000
--- a/extensions/spring-cloud-config-client/runtime/src/main/java/io/quarkus/spring/cloud/config/client/runtime/SpringCloudConfigServerClientConfigSourceProvider.java
+++ /dev/null
@@ -1,117 +0,0 @@
-package io.quarkus.spring.cloud.config.client.runtime;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.eclipse.microprofile.config.spi.ConfigSource;
-import org.eclipse.microprofile.config.spi.ConfigSourceProvider;
-import org.jboss.logging.Logger;
-
-import io.quarkus.runtime.TlsConfig;
-
-public class SpringCloudConfigServerClientConfigSourceProvider implements ConfigSourceProvider {
-
- private static final Logger log = Logger.getLogger(SpringCloudConfigServerClientConfigSourceProvider.class);
-
- private final SpringCloudConfigClientConfig springCloudConfigClientConfig;
- private final String applicationName;
- private final String activeProfile;
-
- private final SpringCloudConfigClientGateway springCloudConfigClientGateway;
-
- public SpringCloudConfigServerClientConfigSourceProvider(SpringCloudConfigClientConfig springCloudConfigClientConfig,
- String applicationName,
- String activeProfile, TlsConfig tlsConfig) {
- this.springCloudConfigClientConfig = springCloudConfigClientConfig;
- this.applicationName = applicationName;
- this.activeProfile = activeProfile;
-
- springCloudConfigClientGateway = new VertxSpringCloudConfigGateway(springCloudConfigClientConfig, tlsConfig);
- }
-
- @Override
- public Iterable getConfigSources(ClassLoader forClassLoader) {
- List result = new ArrayList<>();
- try {
- boolean connectionTimeoutIsGreaterThanZero = !springCloudConfigClientConfig.connectionTimeout.isNegative()
- && !springCloudConfigClientConfig.connectionTimeout.isZero();
- boolean readTimeoutIsGreaterThanZero = !springCloudConfigClientConfig.readTimeout.isNegative()
- && !springCloudConfigClientConfig.readTimeout.isZero();
- Response response;
- // Check if configured timeouts are greater than zero in order to avoid an exception on atMost method
- if (connectionTimeoutIsGreaterThanZero || readTimeoutIsGreaterThanZero)
- response = springCloudConfigClientGateway.exchange(applicationName, activeProfile).await()
- .atMost(springCloudConfigClientConfig.connectionTimeout
- .plus(springCloudConfigClientConfig.readTimeout.multipliedBy(2)));
- else {
- response = springCloudConfigClientGateway.exchange(applicationName, activeProfile).await().indefinitely();
- }
- if (response != null) {
- final List propertySources = response.getPropertySources();
- Collections.reverse(propertySources); // reverse the property sources so we can increment the ordinal from lower priority to higher
- for (int i = 0; i < propertySources.size(); i++) {
- final Response.PropertySource propertySource = propertySources.get(i);
- // Property sources obtained from Spring Cloud Config are expected to have a higher priority than even system properties
- // 400 is the ordinal of SysPropConfigSource, so we use 450 here
- result.add(new InMemoryConfigSource(450 + i, propertySource.getName(),
- propertySource.getSource()));
- }
- }
- } catch (Exception e) {
- final String errorMessage = "Unable to obtain configuration from Spring Cloud Config Server at "
- + springCloudConfigClientConfig.url;
- if (springCloudConfigClientConfig.failFast) {
- throw new RuntimeException(errorMessage, e);
- } else {
- log.error(errorMessage, e);
- return Collections.emptyList();
- }
- } finally {
- springCloudConfigClientGateway.close();
- }
- return result;
-
- }
-
- private static final class InMemoryConfigSource implements ConfigSource {
-
- private final Map values = new HashMap<>();
- private final int ordinal;
- private final String name;
-
- private InMemoryConfigSource(int ordinal, String name, Map source) {
- this.ordinal = ordinal;
- this.name = name;
- this.values.putAll(source);
- }
-
- @Override
- public Map getProperties() {
- return values;
- }
-
- @Override
- public Set getPropertyNames() {
- return values.keySet();
- }
-
- @Override
- public int getOrdinal() {
- return ordinal;
- }
-
- @Override
- public String getValue(String propertyName) {
- return values.get(propertyName);
- }
-
- @Override
- public String getName() {
- return name;
- }
- }
-}
diff --git a/extensions/spring-cloud-config-client/runtime/src/main/java/io/quarkus/spring/cloud/config/client/runtime/VertxSpringCloudConfigGateway.java b/extensions/spring-cloud-config-client/runtime/src/main/java/io/quarkus/spring/cloud/config/client/runtime/VertxSpringCloudConfigGateway.java
index fee1dc0966d97..6c23a986f0063 100644
--- a/extensions/spring-cloud-config-client/runtime/src/main/java/io/quarkus/spring/cloud/config/client/runtime/VertxSpringCloudConfigGateway.java
+++ b/extensions/spring-cloud-config-client/runtime/src/main/java/io/quarkus/spring/cloud/config/client/runtime/VertxSpringCloudConfigGateway.java
@@ -11,7 +11,6 @@
import java.util.List;
import java.util.Map;
import java.util.Optional;
-import java.util.stream.Collectors;
import org.jboss.logging.Logger;
@@ -19,7 +18,6 @@
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
-import io.quarkus.runtime.TlsConfig;
import io.quarkus.runtime.util.ClassPathUtils;
import io.smallrye.mutiny.Uni;
import io.vertx.core.VertxOptions;
@@ -42,21 +40,21 @@ public class VertxSpringCloudConfigGateway implements SpringCloudConfigClientGat
private static final String PKS_12 = "PKS12";
private static final String JKS = "JKS";
- private final SpringCloudConfigClientConfig springCloudConfigClientConfig;
+ private final SpringCloudConfigClientConfig config;
private final Vertx vertx;
private final WebClient webClient;
private final URI baseURI;
- public VertxSpringCloudConfigGateway(SpringCloudConfigClientConfig springCloudConfigClientConfig, TlsConfig tlsConfig) {
- this.springCloudConfigClientConfig = springCloudConfigClientConfig;
+ public VertxSpringCloudConfigGateway(SpringCloudConfigClientConfig config) {
+ this.config = config;
try {
- this.baseURI = determineBaseUri(springCloudConfigClientConfig);
+ this.baseURI = determineBaseUri(config);
} catch (URISyntaxException e) {
- throw new IllegalArgumentException("Value: '" + springCloudConfigClientConfig.url
+ throw new IllegalArgumentException("Value: '" + config.url()
+ "' of property 'quarkus.spring-cloud-config.url' is invalid", e);
}
this.vertx = createVertxInstance();
- this.webClient = createHttpClient(vertx, springCloudConfigClientConfig, tlsConfig);
+ this.webClient = createHttpClient(vertx, config);
}
private Vertx createVertxInstance() {
@@ -80,32 +78,29 @@ private Vertx createVertxInstance() {
return vertx;
}
- public static WebClient createHttpClient(Vertx vertx, SpringCloudConfigClientConfig springCloudConfig,
- TlsConfig tlsConfig) {
-
+ public static WebClient createHttpClient(Vertx vertx, SpringCloudConfigClientConfig config) {
WebClientOptions webClientOptions = new WebClientOptions()
- .setConnectTimeout((int) springCloudConfig.connectionTimeout.toMillis())
- .setIdleTimeout((int) springCloudConfig.readTimeout.getSeconds());
+ .setConnectTimeout((int) config.connectionTimeout().toMillis())
+ .setIdleTimeout((int) config.readTimeout().getSeconds());
- boolean trustAll = springCloudConfig.trustCerts || tlsConfig.trustAll;
try {
- if (springCloudConfig.trustStore.isPresent()) {
- Path trustStorePath = springCloudConfig.trustStore.get();
+ if (config.trustStore().isPresent()) {
+ Path trustStorePath = config.trustStore().get();
String type = determineStoreType(trustStorePath);
- KeyStoreOptionsBase storeOptions = storeOptions(trustStorePath, springCloudConfig.trustStorePassword,
+ KeyStoreOptionsBase storeOptions = storeOptions(trustStorePath, config.trustStorePassword(),
createStoreOptions(type));
if (isPfx(type)) {
webClientOptions.setPfxTrustOptions((PfxOptions) storeOptions);
} else {
webClientOptions.setTrustStoreOptions((JksOptions) storeOptions);
}
- } else if (trustAll) {
+ } else if (config.trustCerts()) {
skipVerify(webClientOptions);
}
- if (springCloudConfig.keyStore.isPresent()) {
- Path keyStorePath = springCloudConfig.keyStore.get();
+ if (config.keyStore().isPresent()) {
+ Path keyStorePath = config.keyStore().get();
String type = determineStoreType(keyStorePath);
- KeyStoreOptionsBase storeOptions = storeOptions(keyStorePath, springCloudConfig.keyStorePassword,
+ KeyStoreOptionsBase storeOptions = storeOptions(keyStorePath, config.keyStorePassword(),
createStoreOptions(type));
if (isPfx(type)) {
webClientOptions.setPfxKeyCertOptions((PfxOptions) storeOptions);
@@ -171,7 +166,7 @@ private static byte[] allBytes(InputStream inputStream) throws Exception {
}
private URI determineBaseUri(SpringCloudConfigClientConfig springCloudConfigClientConfig) throws URISyntaxException {
- String url = springCloudConfigClientConfig.url;
+ String url = springCloudConfigClientConfig.url();
if (null == url || url.isEmpty()) {
throw new IllegalArgumentException(
"The 'quarkus.spring-cloud-config.url' property cannot be empty");
@@ -182,31 +177,30 @@ private URI determineBaseUri(SpringCloudConfigClientConfig springCloudConfigClie
return new URI(url);
}
- private String finalURI(String applicationName, String profile) throws URISyntaxException {
+ private String finalURI(String applicationName, String profile) {
String path = baseURI.getPath();
List finalPathSegments = new ArrayList();
finalPathSegments.add(path);
finalPathSegments.add(applicationName);
finalPathSegments.add(profile);
- if (springCloudConfigClientConfig.label.isPresent()) {
- finalPathSegments.add(springCloudConfigClientConfig.label.get());
+ if (config.label().isPresent()) {
+ finalPathSegments.add(config.label().get());
}
- return finalPathSegments.stream().collect(Collectors.joining("/"));
+ return String.join("/", finalPathSegments);
}
@Override
- public Uni exchange(String applicationName, String profile) throws Exception {
+ public Uni exchange(String applicationName, String profile) {
final String requestURI = finalURI(applicationName, profile);
String finalURI = getFinalURI(applicationName, profile);
HttpRequest request = webClient
.get(getPort(baseURI), baseURI.getHost(), requestURI)
.ssl(isHttps(baseURI))
.putHeader("Accept", "application/json");
- if (springCloudConfigClientConfig.usernameAndPasswordSet()) {
- request.basicAuthentication(springCloudConfigClientConfig.username.get(),
- springCloudConfigClientConfig.password.get());
+ if (config.usernameAndPasswordSet()) {
+ request.basicAuthentication(config.username().get(), config.password().get());
}
- for (Map.Entry entry : springCloudConfigClientConfig.headers.entrySet()) {
+ for (Map.Entry entry : config.headers().entrySet()) {
request.putHeader(entry.getKey(), entry.getValue());
}
log.debug("Attempting to read configuration from '" + finalURI + "'.");
@@ -238,8 +232,8 @@ private int getPort(URI uri) {
private String getFinalURI(String applicationName, String profile) {
String finalURI = baseURI.toString() + "/" + applicationName + "/" + profile;
- if (springCloudConfigClientConfig.label.isPresent()) {
- finalURI = "/" + springCloudConfigClientConfig.label.get();
+ if (config.label().isPresent()) {
+ finalURI = "/" + config.label().get();
}
return finalURI;
}
@@ -249,5 +243,4 @@ public void close() {
this.webClient.close();
this.vertx.closeAndAwait();
}
-
}
diff --git a/extensions/spring-cloud-config-client/runtime/src/test/java/io/quarkus/spring/cloud/config/client/runtime/SpringCloudConfigClientGatewayTest.java b/extensions/spring-cloud-config-client/runtime/src/test/java/io/quarkus/spring/cloud/config/client/runtime/SpringCloudConfigClientGatewayTest.java
index b00e198cd7614..1a8f492534ba1 100644
--- a/extensions/spring-cloud-config-client/runtime/src/test/java/io/quarkus/spring/cloud/config/client/runtime/SpringCloudConfigClientGatewayTest.java
+++ b/extensions/spring-cloud-config-client/runtime/src/test/java/io/quarkus/spring/cloud/config/client/runtime/SpringCloudConfigClientGatewayTest.java
@@ -2,6 +2,7 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.entry;
+import static org.mockito.Mockito.when;
import java.io.IOException;
import java.nio.charset.Charset;
@@ -13,20 +14,18 @@
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.client.WireMock;
-import io.quarkus.runtime.TlsConfig;
-
class SpringCloudConfigClientGatewayTest {
private static final int MOCK_SERVER_PORT = 9300;
private static final WireMockServer wireMockServer = new WireMockServer(MOCK_SERVER_PORT);
- private static final SpringCloudConfigClientConfig springCloudConfigClientConfig = configForTesting();
- private final SpringCloudConfigClientGateway sut = new VertxSpringCloudConfigGateway(
- springCloudConfigClientConfig, new TlsConfig());
+ private static final SpringCloudConfigClientConfig config = configForTesting();
+ private final SpringCloudConfigClientGateway sut = new VertxSpringCloudConfigGateway(config);
@BeforeAll
static void start() {
@@ -43,7 +42,7 @@ void testBasicExchange() throws Exception {
final String applicationName = "foo";
final String profile = "dev";
final String springCloudConfigUrl = String.format(
- "/%s/%s/%s", applicationName, profile, springCloudConfigClientConfig.label.get());
+ "/%s/%s/%s", applicationName, profile, config.label().get());
wireMockServer.stubFor(WireMock.get(springCloudConfigUrl).willReturn(WireMock
.okJson(getJsonStringForApplicationAndProfile(applicationName, profile))));
@@ -76,17 +75,17 @@ private String getJsonStringForApplicationAndProfile(String applicationName, Str
}
private static SpringCloudConfigClientConfig configForTesting() {
- SpringCloudConfigClientConfig springCloudConfigClientConfig = new SpringCloudConfigClientConfig();
- springCloudConfigClientConfig.url = "http://localhost:" + MOCK_SERVER_PORT;
- springCloudConfigClientConfig.label = Optional.of("master");
- springCloudConfigClientConfig.connectionTimeout = Duration.ZERO;
- springCloudConfigClientConfig.readTimeout = Duration.ZERO;
- springCloudConfigClientConfig.username = Optional.empty();
- springCloudConfigClientConfig.password = Optional.empty();
- springCloudConfigClientConfig.trustStore = Optional.empty();
- springCloudConfigClientConfig.keyStore = Optional.empty();
- springCloudConfigClientConfig.trustCerts = false;
- springCloudConfigClientConfig.headers = new HashMap<>();
- return springCloudConfigClientConfig;
+ SpringCloudConfigClientConfig config = Mockito.mock(SpringCloudConfigClientConfig.class);
+ when(config.url()).thenReturn("http://localhost:" + MOCK_SERVER_PORT);
+ when(config.label()).thenReturn(Optional.of("master"));
+ when(config.connectionTimeout()).thenReturn(Duration.ZERO);
+ when(config.readTimeout()).thenReturn(Duration.ZERO);
+ when(config.username()).thenReturn(Optional.empty());
+ when(config.password()).thenReturn(Optional.empty());
+ when(config.trustStore()).thenReturn(Optional.empty());
+ when(config.keyStore()).thenReturn(Optional.empty());
+ when(config.trustCerts()).thenReturn(false);
+ when(config.headers()).thenReturn(new HashMap<>());
+ return config;
}
}
diff --git a/integration-tests/spring-cloud-config-client/pom.xml b/integration-tests/spring-cloud-config-client/pom.xml
index 8759dca0b8220..eb6a84b7b5edc 100644
--- a/integration-tests/spring-cloud-config-client/pom.xml
+++ b/integration-tests/spring-cloud-config-client/pom.xml
@@ -15,16 +15,12 @@
io.quarkus
- quarkus-resteasy
+ quarkus-resteasy-jackson
io.quarkus
quarkus-spring-cloud-config-client
-
- io.quarkus
- quarkus-config-yaml
-
io.quarkus
quarkus-junit5
@@ -44,20 +40,7 @@
io.quarkus
- quarkus-config-yaml-deployment
- ${project.version}
- pom
- test
-
-
- *
- *
-
-
-
-
- io.quarkus
- quarkus-resteasy-deployment
+ quarkus-resteasy-jackson-deployment
${project.version}
pom
test
@@ -98,45 +81,4 @@
-
-
-
- native
-
-
- native
-
-
-
-
-
-
- uk.co.automatictester
- wiremock-maven-plugin
-
-
- wiremock-start
- compile
-
- stop
- run
-
-
- target/classes
- --port=8089 --disable-banner
-
-
-
- wiremock-stop
- post-integration-test
-
- stop
-
-
-
-
-
-
-
-
diff --git a/integration-tests/spring-cloud-config-client/src/main/java/io/quarkus/it/spring/config/server/client/ConfigResource.java b/integration-tests/spring-cloud-config-client/src/main/java/io/quarkus/it/spring/config/server/client/ConfigResource.java
new file mode 100644
index 0000000000000..f5ec994839597
--- /dev/null
+++ b/integration-tests/spring-cloud-config-client/src/main/java/io/quarkus/it/spring/config/server/client/ConfigResource.java
@@ -0,0 +1,33 @@
+package io.quarkus.it.spring.config.server.client;
+
+import javax.inject.Inject;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import io.quarkus.runtime.annotations.RegisterForReflection;
+import io.smallrye.config.SmallRyeConfig;
+
+@Path("/config")
+@Produces(MediaType.APPLICATION_JSON)
+public class ConfigResource {
+ @Inject
+ SmallRyeConfig config;
+
+ @GET
+ @Path("/{name}")
+ public Response configValue(@PathParam("name") final String name) {
+ return Response.ok(config.getConfigValue(name)).build();
+ }
+
+ @RegisterForReflection(targets = {
+ org.eclipse.microprofile.config.ConfigValue.class,
+ io.smallrye.config.ConfigValue.class
+ })
+ public static class ConfigValueReflection {
+
+ }
+}
diff --git a/integration-tests/spring-cloud-config-client/src/main/java/io/quarkus/it/spring/config/server/client/GreetingResource.java b/integration-tests/spring-cloud-config-client/src/main/java/io/quarkus/it/spring/config/server/client/GreetingResource.java
deleted file mode 100644
index 5c8603cdf1b60..0000000000000
--- a/integration-tests/spring-cloud-config-client/src/main/java/io/quarkus/it/spring/config/server/client/GreetingResource.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package io.quarkus.it.spring.config.server.client;
-
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-
-import org.eclipse.microprofile.config.inject.ConfigProperty;
-
-@Path("/greeting")
-public class GreetingResource {
-
- @ConfigProperty(name = "greeting.message")
- String message;
-
- @GET
- public String greet() {
- return message;
- }
-}
diff --git a/integration-tests/spring-cloud-config-client/src/main/resources/application.properties b/integration-tests/spring-cloud-config-client/src/main/resources/application.properties
new file mode 100644
index 0000000000000..231cfae46ea00
--- /dev/null
+++ b/integration-tests/spring-cloud-config-client/src/main/resources/application.properties
@@ -0,0 +1,3 @@
+quarkus.config.profile.parent=common
+
+quarkus.application.name=a-bootiful-client
diff --git a/integration-tests/spring-cloud-config-client/src/main/resources/application.yaml b/integration-tests/spring-cloud-config-client/src/main/resources/application.yaml
deleted file mode 100644
index aacd3714ab37c..0000000000000
--- a/integration-tests/spring-cloud-config-client/src/main/resources/application.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-'%prod':
- quarkus:
- spring-cloud-config:
- url: http://localhost:8089/base
- username: user
- password: pass
- enabled: true
- headers:
- h1: v1
- h2: v2
-quarkus:
- application:
- name: a-bootiful-client
-
-greeting:
- message: hello from application.properties
diff --git a/integration-tests/spring-cloud-config-client/src/main/resources/mappings/a-bootiful-client-prod.json b/integration-tests/spring-cloud-config-client/src/main/resources/mappings/a-bootiful-client-prod.json
deleted file mode 100644
index eea420c151da5..0000000000000
--- a/integration-tests/spring-cloud-config-client/src/main/resources/mappings/a-bootiful-client-prod.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "request": {
- "method": "GET",
- "urlPattern": "/base/a-bootiful-client/prod",
- "basicAuth" : {
- "username" : "user",
- "password" : "pass"
- },
- "headers" : {
- "Accept" : {
- "contains" : "application/json"
- },
- "h1": {
- "equalTo": "v1"
- },
- "h2": {
- "equalTo": "v2"
- }
- }
- },
- "response": {
- "status": 200,
- "headers": {
- "Content-Type": "application/json"
- },
- "bodyFileName": "a-bootiful-client-prod.json"
- }
-}
diff --git a/integration-tests/spring-cloud-config-client/src/test/java/io/quarkus/spring/cloud/config/client/runtime/GreetingResourceIT.java b/integration-tests/spring-cloud-config-client/src/test/java/io/quarkus/spring/cloud/config/client/runtime/GreetingResourceIT.java
deleted file mode 100644
index 9cae065c4bc52..0000000000000
--- a/integration-tests/spring-cloud-config-client/src/test/java/io/quarkus/spring/cloud/config/client/runtime/GreetingResourceIT.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package io.quarkus.spring.cloud.config.client.runtime;
-
-import io.quarkus.test.junit.QuarkusIntegrationTest;
-
-@QuarkusIntegrationTest
-public class GreetingResourceIT extends GreetingResourceTest {
-
- @Override
- protected String getExpectedValue() {
- return "hello from spring cloud config server";
- }
-}
diff --git a/integration-tests/spring-cloud-config-client/src/test/java/io/quarkus/spring/cloud/config/client/runtime/GreetingResourceTest.java b/integration-tests/spring-cloud-config-client/src/test/java/io/quarkus/spring/cloud/config/client/runtime/GreetingResourceTest.java
deleted file mode 100644
index 50aabe5bac9d6..0000000000000
--- a/integration-tests/spring-cloud-config-client/src/test/java/io/quarkus/spring/cloud/config/client/runtime/GreetingResourceTest.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package io.quarkus.spring.cloud.config.client.runtime;
-
-import static io.restassured.RestAssured.given;
-import static org.hamcrest.CoreMatchers.is;
-
-import org.junit.jupiter.api.Test;
-
-import io.quarkus.test.junit.QuarkusTest;
-
-@QuarkusTest
-class GreetingResourceTest {
-
- @Test
- void testGreeting() {
- given()
- .when().get("/greeting")
- .then()
- .statusCode(200)
- .body(is(getExpectedValue()));
-
- }
-
- protected String getExpectedValue() {
- return "hello from application.properties";
- }
-}
diff --git a/integration-tests/spring-cloud-config-client/src/test/java/io/quarkus/spring/cloud/config/client/runtime/SpringCloudConfigClientIT.java b/integration-tests/spring-cloud-config-client/src/test/java/io/quarkus/spring/cloud/config/client/runtime/SpringCloudConfigClientIT.java
new file mode 100644
index 0000000000000..bacfd270afed5
--- /dev/null
+++ b/integration-tests/spring-cloud-config-client/src/test/java/io/quarkus/spring/cloud/config/client/runtime/SpringCloudConfigClientIT.java
@@ -0,0 +1,8 @@
+package io.quarkus.spring.cloud.config.client.runtime;
+
+import io.quarkus.test.junit.QuarkusIntegrationTest;
+
+@QuarkusIntegrationTest
+public class SpringCloudConfigClientIT extends SpringCloudConfigClientTest {
+
+}
diff --git a/integration-tests/spring-cloud-config-client/src/test/java/io/quarkus/spring/cloud/config/client/runtime/SpringCloudConfigClientTest.java b/integration-tests/spring-cloud-config-client/src/test/java/io/quarkus/spring/cloud/config/client/runtime/SpringCloudConfigClientTest.java
new file mode 100644
index 0000000000000..f8eed37182f2c
--- /dev/null
+++ b/integration-tests/spring-cloud-config-client/src/test/java/io/quarkus/spring/cloud/config/client/runtime/SpringCloudConfigClientTest.java
@@ -0,0 +1,49 @@
+package io.quarkus.spring.cloud.config.client.runtime;
+
+import static io.restassured.RestAssured.given;
+import static javax.ws.rs.core.Response.Status.OK;
+import static org.hamcrest.Matchers.equalTo;
+
+import org.junit.jupiter.api.Test;
+
+import io.quarkus.test.common.QuarkusTestResource;
+import io.quarkus.test.junit.QuarkusTest;
+
+@QuarkusTest
+@QuarkusTestResource(SpringCloudConfigServerResource.class)
+public class SpringCloudConfigClientTest {
+ @Test
+ void config() {
+ given()
+ .get("/config/{name}", "greeting.message")
+ .then()
+ .statusCode(OK.getStatusCode())
+ .body("value", equalTo("hello from spring cloud config server"));
+ }
+
+ @Test
+ void ordinal() {
+ given()
+ .get("/config/{name}", "foo")
+ .then()
+ .statusCode(OK.getStatusCode())
+ .body("value", equalTo("from foo development"))
+ .body("sourceName", equalTo("https://github.com/spring-cloud-samples/config-repo/testapp-prod.yml"));
+
+ given()
+ .get("/config/{name}", "info.description")
+ .then()
+ .statusCode(OK.getStatusCode())
+ .body("value", equalTo("Sample"));
+ }
+
+ @Test
+ void multiple() {
+ given()
+ .get("/config/{name}", "common")
+ .then()
+ .statusCode(OK.getStatusCode())
+ .body("value", equalTo("common"))
+ .body("sourceName", equalTo("common"));
+ }
+}
diff --git a/integration-tests/spring-cloud-config-client/src/test/java/io/quarkus/spring/cloud/config/client/runtime/SpringCloudConfigServerResource.java b/integration-tests/spring-cloud-config-client/src/test/java/io/quarkus/spring/cloud/config/client/runtime/SpringCloudConfigServerResource.java
new file mode 100644
index 0000000000000..6914e7e5ba9c5
--- /dev/null
+++ b/integration-tests/spring-cloud-config-client/src/test/java/io/quarkus/spring/cloud/config/client/runtime/SpringCloudConfigServerResource.java
@@ -0,0 +1,79 @@
+package io.quarkus.spring.cloud.config.client.runtime;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+
+import org.apache.commons.io.IOUtils;
+
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import com.sun.net.httpserver.HttpServer;
+
+import io.quarkus.test.common.QuarkusTestResourceLifecycleManager;
+
+public class SpringCloudConfigServerResource implements QuarkusTestResourceLifecycleManager {
+ private HttpServer httpServer;
+
+ @Override
+ public Map start() {
+ int port = 8089;
+ try {
+ httpServer = HttpServer.create(new InetSocketAddress(port), 0);
+ httpServer.createContext("/base/a-bootiful-client/test", new SpringCloudConfigServerHandler("config.json"));
+ httpServer.createContext("/base/a-bootiful-client/prod", new SpringCloudConfigServerHandler("config.json"));
+ httpServer.createContext("/base/a-bootiful-client/common",
+ new SpringCloudConfigServerHandler("config-common.json"));
+ httpServer.start();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ return Map.of(
+ "quarkus.spring-cloud-config.url", "http://localhost:" + port + "/base",
+ "quarkus.spring-cloud-config.username", "user",
+ "quarkus.spring-cloud-config.password", "pass",
+ "quarkus.spring-cloud-config.enabled", "true",
+ "quarkus.spring-cloud-config.headers.h1", "v1",
+ "quarkus.spring-cloud-config.headers.h2", "v2");
+ }
+
+ @Override
+ public void stop() {
+ if (httpServer != null) {
+ httpServer.stop(0);
+ }
+ }
+
+ private static class SpringCloudConfigServerHandler implements HttpHandler {
+ private final String resource;
+
+ public SpringCloudConfigServerHandler(final String resource) {
+ this.resource = resource;
+ }
+
+ @Override
+ public void handle(final HttpExchange exchange) throws IOException {
+ URL resource = Thread.currentThread().getContextClassLoader().getResource(this.resource);
+ if (resource == null) {
+ exchange.sendResponseHeaders(400, 0);
+ return;
+ }
+
+ if (!"v1".equals(exchange.getRequestHeaders().getFirst("h1"))) {
+ exchange.sendResponseHeaders(400, 0);
+ }
+ if (!"v2".equals(exchange.getRequestHeaders().getFirst("h2"))) {
+ exchange.sendResponseHeaders(400, 0);
+ }
+
+ String body = IOUtils.toString(resource, StandardCharsets.UTF_8);
+ exchange.getResponseHeaders().add("Content-Type", "application/json");
+ exchange.sendResponseHeaders(200, body.length());
+ exchange.getResponseBody().write(body.getBytes());
+ exchange.getResponseBody().close();
+ }
+ }
+}
diff --git a/integration-tests/spring-cloud-config-client/src/test/resources/config-common.json b/integration-tests/spring-cloud-config-client/src/test/resources/config-common.json
new file mode 100644
index 0000000000000..551470dd60b01
--- /dev/null
+++ b/integration-tests/spring-cloud-config-client/src/test/resources/config-common.json
@@ -0,0 +1,18 @@
+{
+ "name": "common",
+ "profiles": [
+ "common"
+ ],
+ "label": "master",
+ "version": "bb51f4173258ae3481c61b95b503c13862ccfba7",
+ "state": null,
+ "propertySources": [
+ {
+ "name": "common",
+ "source": {
+ "foo": "common",
+ "common": "common"
+ }
+ }
+ ]
+}
diff --git a/integration-tests/spring-cloud-config-client/src/main/resources/__files/a-bootiful-client-prod.json b/integration-tests/spring-cloud-config-client/src/test/resources/config.json
similarity index 96%
rename from integration-tests/spring-cloud-config-client/src/main/resources/__files/a-bootiful-client-prod.json
rename to integration-tests/spring-cloud-config-client/src/test/resources/config.json
index ab01d933fac00..0768660a35c7e 100644
--- a/integration-tests/spring-cloud-config-client/src/main/resources/__files/a-bootiful-client-prod.json
+++ b/integration-tests/spring-cloud-config-client/src/test/resources/config.json
@@ -1,7 +1,7 @@
{
"name": "a-bootiful-client",
"profiles": [
- "prod"
+ "prod","test"
],
"label": "master",
"version": "bb51f4173258ae3481c61b95b503c13862ccfba7",
@@ -23,4 +23,4 @@
}
}
]
-}
\ No newline at end of file
+}
From cc4249eed74c1fa5e10f3047174976ce12f3f69d Mon Sep 17 00:00:00 2001
From: Holly Cummins
Date: Mon, 23 Jan 2023 15:40:27 +0000
Subject: [PATCH 020/250] Add information about sizes and formats
---
docs/src/main/asciidoc/extension-metadata.adoc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/src/main/asciidoc/extension-metadata.adoc b/docs/src/main/asciidoc/extension-metadata.adoc
index 5a6f835c86b5d..b2abc23e75228 100644
--- a/docs/src/main/asciidoc/extension-metadata.adoc
+++ b/docs/src/main/asciidoc/extension-metadata.adoc
@@ -51,7 +51,7 @@ metadata:
<5> Categories the extension should appear under on https://code.quarkus.io[code.quarkus.io]. This field can be omitted, the extension will still be listed on https://code.quarkus.io[code.quarkus.io] but won't be categorized
<6> Maturity status that could be `stable`, `preview`, `experimental`. It is up to extension maintainers to evaluate the maturity status and communicate it to the users
<7> Link to the extension guide or documentation page
-<8> Link to an externally hosted image. This is used in the Quarkus dev tools as the extension icon. Alternatively, if you https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/customizing-your-repositorys-social-media-preview[set the social media preview] on your extensions source code repository, the tools will pick up that image.
+<8> Link to an externally hosted image. This is used in the Quarkus dev tools as the extension icon. It should be square, and any resolution greater than 220 pixels. Supported formats are png, jpeg, tiff, webp, and svg. Alternatively, if you https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/customizing-your-repositorys-social-media-preview[set the social media preview] on the extension's source code repository, the tools will pick up that image.
<9> https://quarkus.io/guides/extension-codestart[Codestart] information
<10> Configuration prefix
From c96a557c5786eca445aca110829b4d7156f14129 Mon Sep 17 00:00:00 2001
From: Sebastian Schuster
Date: Tue, 24 Jan 2023 20:02:03 +0100
Subject: [PATCH 021/250] 30584 updated mssql jdbc driver to 11.2.3
---
bom/application/pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/bom/application/pom.xml b/bom/application/pom.xml
index 6c5697c80ee73..bc757cdd7bc1c 100644
--- a/bom/application/pom.xml
+++ b/bom/application/pom.xml
@@ -124,7 +124,7 @@
42.5.1
3.1.1
8.0.30
- 11.2.0.jre11
+ 11.2.3.jre11
1.6.7
21.5.0.0
10.14.2.0
From d9489232d7ef1442cbd6cdcfb600d243351770fc Mon Sep 17 00:00:00 2001
From: Ales Justin
Date: Tue, 24 Jan 2023 14:42:07 +0100
Subject: [PATCH 022/250] Add more log to GrpcDuplicatedContextGrpcInterceptor.
---
.../supports/context/GrpcDuplicatedContextGrpcInterceptor.java | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/extensions/grpc/runtime/src/main/java/io/quarkus/grpc/runtime/supports/context/GrpcDuplicatedContextGrpcInterceptor.java b/extensions/grpc/runtime/src/main/java/io/quarkus/grpc/runtime/supports/context/GrpcDuplicatedContextGrpcInterceptor.java
index ff05af4e80711..ae45cba61ede6 100644
--- a/extensions/grpc/runtime/src/main/java/io/quarkus/grpc/runtime/supports/context/GrpcDuplicatedContextGrpcInterceptor.java
+++ b/extensions/grpc/runtime/src/main/java/io/quarkus/grpc/runtime/supports/context/GrpcDuplicatedContextGrpcInterceptor.java
@@ -84,7 +84,7 @@ private synchronized ServerCall.Listener getDelegate() {
delegate = supplier.get();
} catch (Throwable t) {
// If the interceptor supplier throws an exception, catch it, and close the call.
- log.warn("Unable to retrieve gRPC Server call listener", t);
+ log.warn("Unable to retrieve gRPC Server call listener, see the cause below.");
close(t);
return null;
}
@@ -100,6 +100,7 @@ private void close(Throwable t) {
Throwable nt = ehp.transform(t);
StatusException sre = (StatusException) ExceptionHandlerProvider.toStatusException(nt, false);
Optional metadata = ExceptionHandlerProvider.toTrailers(nt);
+ log.warn("Closing gRPC call due to an error ...", t);
call.close(sre.getStatus(), metadata.orElse(new Metadata()));
}
}
From ce0e69016cb5265cff4f305dad1cb2bd635ea688 Mon Sep 17 00:00:00 2001
From: Roberto Cortez
Date: Wed, 25 Jan 2023 13:11:30 +0000
Subject: [PATCH 023/250] Remove lookup by profile when updating configurations
---
.../devmode/console/ConfigEditorProcessor.java | 16 +++-------------
1 file changed, 3 insertions(+), 13 deletions(-)
diff --git a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/ConfigEditorProcessor.java b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/ConfigEditorProcessor.java
index 456320c9d91e3..abb3c93e65cc6 100644
--- a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/ConfigEditorProcessor.java
+++ b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/ConfigEditorProcessor.java
@@ -1,7 +1,5 @@
package io.quarkus.vertx.http.deployment.devmode.console;
-import static io.quarkus.runtime.LaunchMode.DEVELOPMENT;
-
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
@@ -46,7 +44,6 @@
import io.quarkus.devconsole.runtime.spi.DevConsolePostHandler;
import io.quarkus.devconsole.spi.DevConsoleRouteBuildItem;
import io.quarkus.devconsole.spi.DevConsoleRuntimeTemplateInfoBuildItem;
-import io.quarkus.runtime.configuration.ConfigUtils;
import io.quarkus.vertx.http.runtime.devmode.ConfigDescription;
import io.quarkus.vertx.http.runtime.devmode.ConfigDescriptionsManager;
import io.quarkus.vertx.http.runtime.devmode.ConfigDescriptionsRecorder;
@@ -215,7 +212,6 @@ static void updateConfig(Map values) {
if (values != null && !values.isEmpty()) {
try {
Path configPath = getConfigPath();
- List profiles = ConfigUtils.getProfiles();
List lines = Files.readAllLines(configPath);
for (Map.Entry entry : values.entrySet()) {
String name = entry.getKey();
@@ -223,17 +219,11 @@ static void updateConfig(Map values) {
int nameLine = -1;
for (int i = 0, linesSize = lines.size(); i < linesSize; i++) {
String line = lines.get(i);
- for (String profile : profiles) {
- String profileName = !profile.equals(DEVELOPMENT.getDefaultProfile()) ? "%" + profile + "." + name
- : name;
- if (line.startsWith(profileName + "=")) {
- name = profileName;
- nameLine = i;
- break;
- }
+ if (line.startsWith(name + "=")) {
+ nameLine = i;
+ break;
}
}
-
if (nameLine != -1) {
if (value.isEmpty()) {
lines.remove(nameLine);
From 8ba81382036634645f8326f3952d2ca3ab5f91ba Mon Sep 17 00:00:00 2001
From: Matej Novotny
Date: Tue, 24 Jan 2023 15:01:23 +0100
Subject: [PATCH 024/250] Arc - attempt to fix bean types for beans with raw
type superclasses
---
.../java/io/quarkus/arc/processor/Types.java | 18 +++++++----
.../io/quarkus/arc/processor/TypesTest.java | 30 ++++++++++++++++++-
2 files changed, 42 insertions(+), 6 deletions(-)
diff --git a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Types.java b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Types.java
index 54f0af4547bdb..5066d07f874d2 100644
--- a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Types.java
+++ b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Types.java
@@ -517,12 +517,13 @@ private static Set getTypeClosure(ClassInfo classInfo, AnnotationTarget pr
boolean throwOnProducerWildcard,
Map resolvedTypeParameters,
BeanDeployment beanDeployment, BiConsumer> resolvedTypeVariablesConsumer,
- Set unrestrictedBeanTypes) {
+ Set unrestrictedBeanTypes, boolean rawGeneric) {
Set types = new HashSet<>();
List typeParameters = classInfo.typeParameters();
if (typeParameters.isEmpty()
- || !typeParameters.stream().allMatch(it -> resolvedTypeParameters.containsKey(it.identifier()))) {
+ || !typeParameters.stream().allMatch(it -> resolvedTypeParameters.containsKey(it.identifier()))
+ || rawGeneric) {
// Not a parameterized type or a raw type
types.add(Type.create(classInfo.name(), Kind.CLASS));
} else {
@@ -562,7 +563,8 @@ private static Set getTypeClosure(ClassInfo classInfo, AnnotationTarget pr
interfaceClassInfo.typeParameters(), resolvedTypeParameters, beanDeployment.getBeanArchiveIndex());
}
types.addAll(getTypeClosure(interfaceClassInfo, producerFieldOrMethod, false, resolved, beanDeployment,
- resolvedTypeVariablesConsumer, unrestrictedBeanTypes));
+ resolvedTypeVariablesConsumer, unrestrictedBeanTypes,
+ rawGeneric || isRawGeneric(interfaceType, interfaceClassInfo)));
}
}
// Superclass
@@ -576,19 +578,25 @@ private static Set getTypeClosure(ClassInfo classInfo, AnnotationTarget pr
resolvedTypeParameters, beanDeployment.getBeanArchiveIndex());
}
types.addAll(getTypeClosure(superClassInfo, producerFieldOrMethod, false, resolved, beanDeployment,
- resolvedTypeVariablesConsumer, unrestrictedBeanTypes));
+ resolvedTypeVariablesConsumer, unrestrictedBeanTypes,
+ rawGeneric || isRawGeneric(classInfo.superClassType(), superClassInfo)));
}
}
unrestrictedBeanTypes.addAll(types);
return types;
}
+ // if the superclass type is CLASS *AND* and superclass info has type parameters, then it's raw type
+ private static boolean isRawGeneric(Type superClassType, ClassInfo superClassInfo) {
+ return Kind.CLASS.equals(superClassType.kind()) && !superClassInfo.typeParameters().isEmpty();
+ }
+
static Set getTypeClosure(ClassInfo classInfo, AnnotationTarget producerFieldOrMethod,
Map resolvedTypeParameters,
BeanDeployment beanDeployment, BiConsumer> resolvedTypeVariablesConsumer,
Set unrestrictedBeanTypes) {
return getTypeClosure(classInfo, producerFieldOrMethod, true, resolvedTypeParameters, beanDeployment,
- resolvedTypeVariablesConsumer, unrestrictedBeanTypes);
+ resolvedTypeVariablesConsumer, unrestrictedBeanTypes, false);
}
static Set getDelegateTypeClosure(InjectionPointInfo delegateInjectionPoint, BeanDeployment beanDeployment) {
diff --git a/independent-projects/arc/processor/src/test/java/io/quarkus/arc/processor/TypesTest.java b/independent-projects/arc/processor/src/test/java/io/quarkus/arc/processor/TypesTest.java
index 86ddf65858ee4..64f9539567b85 100644
--- a/independent-projects/arc/processor/src/test/java/io/quarkus/arc/processor/TypesTest.java
+++ b/independent-projects/arc/processor/src/test/java/io/quarkus/arc/processor/TypesTest.java
@@ -30,7 +30,8 @@ public class TypesTest {
@Test
public void testGetTypeClosure() throws IOException {
IndexView index = Basics.index(Foo.class, Baz.class, Producer.class, Object.class, List.class, Collection.class,
- Iterable.class, Set.class, Eagle.class, Bird.class, Animal.class, AnimalHolder.class);
+ Iterable.class, Set.class, Eagle.class, Bird.class, Animal.class, AnimalHolder.class, MyRawBean.class,
+ MyBean.class, MyInterface.class, MySuperInterface.class);
DotName bazName = DotName.createSimple(Baz.class.getName());
DotName fooName = DotName.createSimple(Foo.class.getName());
DotName producerName = DotName.createSimple(Producer.class.getName());
@@ -93,6 +94,17 @@ public void testGetTypeClosure() throws IOException {
assertDoesNotThrow(
() -> verifyEagleTypes(Types.getClassBeanTypeClosure(index.getClassByName(DotName.createSimple(Eagle.class)),
dummyDeployment)));
+
+ // raw type bean
+ Set rawBeanTypes = Types.getClassBeanTypeClosure(index.getClassByName(DotName.createSimple(MyRawBean.class)),
+ dummyDeployment);
+ assertEquals(rawBeanTypes.size(), 5);
+ assertContainsType(MyRawBean.class, rawBeanTypes);
+ assertContainsType(MyBean.class, rawBeanTypes);
+ assertContainsType(MyInterface.class, rawBeanTypes);
+ // according to JLS, for raw type generics, their superclasses have erasure applied so this should be a match
+ assertContainsType(MySuperInterface.class, rawBeanTypes);
+ assertContainsType(Object.class, rawBeanTypes);
}
private void verifyEagleTypes(Set types) {
@@ -104,6 +116,10 @@ private void verifyEagleTypes(Set types) {
assertEquals(3, types.size());
}
+ private void assertContainsType(Class> clazz, Set rawBeanTypes) {
+ assertTrue(rawBeanTypes.contains(Type.create(DotName.createSimple(clazz.getName()), Kind.CLASS)));
+ }
+
static class Foo {
T field;
@@ -149,4 +165,16 @@ static class Animal {
static class AnimalHolder {
}
+
+ static class MyRawBean extends MyBean {
+ }
+
+ static class MyBean implements MyInterface {
+ }
+
+ interface MyInterface extends MySuperInterface {
+ }
+
+ interface MySuperInterface {
+ }
}
From 1aa81e4d27f15ee0d6321c09827eaf3761ca9564 Mon Sep 17 00:00:00 2001
From: Rolfe Dlugy-Hegwer
Date: Wed, 25 Jan 2023 16:52:12 -0500
Subject: [PATCH 025/250] Add summary to topic
---
.../security-oidc-bearer-authentication-concept.adoc | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/docs/src/main/asciidoc/security-oidc-bearer-authentication-concept.adoc b/docs/src/main/asciidoc/security-oidc-bearer-authentication-concept.adoc
index 0afe0de765411..a24e71228ee2b 100644
--- a/docs/src/main/asciidoc/security-oidc-bearer-authentication-concept.adoc
+++ b/docs/src/main/asciidoc/security-oidc-bearer-authentication-concept.adoc
@@ -6,7 +6,9 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc
[id="security-oidc-bearer-authentication-concept"]
= OIDC Bearer authentication
include::_attributes.adoc[]
-:categories: security
+:categories: security,web
+
+:summary: To secure HTTP access to JAX-RS endpoints in your application, you can use Bearer authentication provided by the Quarkus OpenID Connect (OIDC) extension.
== Overview of the Bearer authentication mechanism in Quarkus
@@ -918,4 +920,4 @@ Note Quarkus `web-app` applications always require `quarkus.oidc.client-id` prop
* xref:security-authentication-mechanisms.adoc#oidc-jwt-oauth2-comparison[Choosing between OpenID Connect, SmallRye JWT, and OAuth2 authentication mechanisms]
* xref:security-authentication-mechanisms.adoc#combining-authentication-mechanisms[Combining authentication mechanisms]
* xref:security-overview-concept.adoc[Quarkus Security overview]
-* xref:security-keycloak-admin-client.adoc[Quarkus Keycloak Admin Client]
\ No newline at end of file
+* xref:security-keycloak-admin-client.adoc[Quarkus Keycloak Admin Client]
From 89412e53ef1bde4a52cad31a78422a37b3ad4d55 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Wed, 25 Jan 2023 22:43:55 +0000
Subject: [PATCH 026/250] Bump bouncycastle.version from 1.71 to 1.72
Bumps `bouncycastle.version` from 1.71 to 1.72.
Updates `bcprov-jdk18on` from 1.71 to 1.72
- [Release notes](https://github.com/bcgit/bc-java/releases)
- [Changelog](https://github.com/bcgit/bc-java/blob/master/docs/releasenotes.html)
- [Commits](https://github.com/bcgit/bc-java/commits)
Updates `bctls-jdk18on` from 1.71 to 1.72
- [Release notes](https://github.com/bcgit/bc-java/releases)
- [Changelog](https://github.com/bcgit/bc-java/blob/master/docs/releasenotes.html)
- [Commits](https://github.com/bcgit/bc-java/commits)
Updates `bcpkix-jdk18on` from 1.71 to 1.72
- [Release notes](https://github.com/bcgit/bc-java/releases)
- [Changelog](https://github.com/bcgit/bc-java/blob/master/docs/releasenotes.html)
- [Commits](https://github.com/bcgit/bc-java/commits)
Updates `bcutil-jdk18on` from 1.71 to 1.72
- [Release notes](https://github.com/bcgit/bc-java/releases)
- [Changelog](https://github.com/bcgit/bc-java/blob/master/docs/releasenotes.html)
- [Commits](https://github.com/bcgit/bc-java/commits)
---
updated-dependencies:
- dependency-name: org.bouncycastle:bcprov-jdk18on
dependency-type: direct:development
update-type: version-update:semver-minor
- dependency-name: org.bouncycastle:bctls-jdk18on
dependency-type: direct:production
update-type: version-update:semver-minor
- dependency-name: org.bouncycastle:bcpkix-jdk18on
dependency-type: direct:production
update-type: version-update:semver-minor
- dependency-name: org.bouncycastle:bcutil-jdk18on
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot]
---
bom/application/pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/bom/application/pom.xml b/bom/application/pom.xml
index 7414d99c2ef52..f5d9a78d54562 100644
--- a/bom/application/pom.xml
+++ b/bom/application/pom.xml
@@ -14,7 +14,7 @@
pom
- 1.71
+ 1.72
1.0.2.3
1.0.14.1
3.0.2
From 41ebc6c8e58b69656f13f19827f2e8f9d47e2ede Mon Sep 17 00:00:00 2001
From: Dan Dunning <2349188+dunningdan@users.noreply.github.com>
Date: Wed, 25 Jan 2023 22:45:02 -0500
Subject: [PATCH 027/250] Update invalid package in guide
---
docs/src/main/asciidoc/liquibase-mongodb.adoc | 2 +-
docs/src/main/asciidoc/liquibase.adoc | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/docs/src/main/asciidoc/liquibase-mongodb.adoc b/docs/src/main/asciidoc/liquibase-mongodb.adoc
index d3bc48679782b..4ea1a8daa85c1 100644
--- a/docs/src/main/asciidoc/liquibase-mongodb.adoc
+++ b/docs/src/main/asciidoc/liquibase-mongodb.adoc
@@ -127,7 +127,7 @@ Quarkus will already have run the migrate operation.
[source,java]
----
-import org.quarkus.liquibase.LiquibaseFactory;
+import io.quarkus.liquibase.LiquibaseFactory;
@ApplicationScoped
public class MigrationService {
diff --git a/docs/src/main/asciidoc/liquibase.adoc b/docs/src/main/asciidoc/liquibase.adoc
index d202b7fe6fb5c..4b5129ef16cd8 100644
--- a/docs/src/main/asciidoc/liquibase.adoc
+++ b/docs/src/main/asciidoc/liquibase.adoc
@@ -124,7 +124,7 @@ Now you can start your application and Quarkus will run the Liquibase's update m
[source,java]
----
-import org.quarkus.liquibase.LiquibaseFactory; <1>
+import io.quarkus.liquibase.LiquibaseFactory; <1>
@ApplicationScoped
public class MigrationService {
@@ -195,7 +195,7 @@ Quarkus will already have run the migrate operation.
[source,java]
----
-import org.quarkus.liquibase.LiquibaseFactory;
+import io.quarkus.liquibase.LiquibaseFactory;
@ApplicationScoped
public class MigrationService {
From 85bcb2eafd8648af5020bf0d39c233206535dc68 Mon Sep 17 00:00:00 2001
From: Alexey Loubyansky
Date: Thu, 26 Jan 2023 08:45:36 +0100
Subject: [PATCH 028/250] Fix NPE obtaining a project map from Maven session
---
.../main/java/io/quarkus/maven/QuarkusBootstrapProvider.java | 3 +++
1 file changed, 3 insertions(+)
diff --git a/devtools/maven/src/main/java/io/quarkus/maven/QuarkusBootstrapProvider.java b/devtools/maven/src/main/java/io/quarkus/maven/QuarkusBootstrapProvider.java
index 2c4e876d7e189..1821722bc8c1f 100644
--- a/devtools/maven/src/main/java/io/quarkus/maven/QuarkusBootstrapProvider.java
+++ b/devtools/maven/src/main/java/io/quarkus/maven/QuarkusBootstrapProvider.java
@@ -66,6 +66,9 @@ static ArtifactKey getProjectId(MavenProject project) {
static Map getProjectMap(MavenSession session) {
final List allProjects = session.getAllProjects();
+ if (allProjects == null) {
+ return Map.of();
+ }
final Map projectModels = new HashMap<>(allProjects.size());
for (MavenProject mp : allProjects) {
mp.getOriginalModel().setPomFile(mp.getFile());
From 34dfe2af05f903ffe0831cde03083e91692ce796 Mon Sep 17 00:00:00 2001
From: Jose
Date: Thu, 26 Jan 2023 09:25:54 +0100
Subject: [PATCH 029/250] Fix support primitive types for fields filtering in
REST Data Panache
Primitive types are cumbersome because are not nullable, so we need to convert them into classes types to deal with this.
Fix https://github.com/quarkusio/quarkus/issues/30605
---
docs/src/main/asciidoc/rest-data-panache.adoc | 2 +-
.../deployment/AbstractGetMethodTest.java | 20 +++++++++
.../panache/deployment/entity/Collection.java | 7 +++
.../deployment/repository/Collection.java | 7 +++
.../methods/ListMethodImplementor.java | 8 +++-
.../methods/StandardMethodImplementor.java | 14 ------
.../utils/SignatureMethodCreator.java | 6 +--
.../panache/deployment/utils/TypeUtils.java | 45 +++++++++++++++++++
8 files changed, 90 insertions(+), 19 deletions(-)
create mode 100644 extensions/panache/rest-data-panache/deployment/src/main/java/io/quarkus/rest/data/panache/deployment/utils/TypeUtils.java
diff --git a/docs/src/main/asciidoc/rest-data-panache.adoc b/docs/src/main/asciidoc/rest-data-panache.adoc
index 38f0af44a6d28..5506edf988b22 100644
--- a/docs/src/main/asciidoc/rest-data-panache.adoc
+++ b/docs/src/main/asciidoc/rest-data-panache.adoc
@@ -407,7 +407,7 @@ Additionally, you can also filter by the entity fields by adding a query param w
]
----
-IMPORTANT: Filtering by fields is only supported for primitive types.
+IMPORTANT: Filtering by fields is only supported for String, Boolean, Character, Double, Float, Integer, Long, Short, Byte and the primitive types.
== Complex filtering to list entities using @NamedQuery
diff --git a/extensions/panache/hibernate-orm-rest-data-panache/deployment/src/test/java/io/quarkus/hibernate/orm/rest/data/panache/deployment/AbstractGetMethodTest.java b/extensions/panache/hibernate-orm-rest-data-panache/deployment/src/test/java/io/quarkus/hibernate/orm/rest/data/panache/deployment/AbstractGetMethodTest.java
index 4f9dd7823d60c..ebc00cdf55fe5 100644
--- a/extensions/panache/hibernate-orm-rest-data-panache/deployment/src/test/java/io/quarkus/hibernate/orm/rest/data/panache/deployment/AbstractGetMethodTest.java
+++ b/extensions/panache/hibernate-orm-rest-data-panache/deployment/src/test/java/io/quarkus/hibernate/orm/rest/data/panache/deployment/AbstractGetMethodTest.java
@@ -86,6 +86,26 @@ void shouldListSimpleObjects() {
.and().body("name", contains("first", "second"));
}
+ @Test
+ void shouldListWithPrimitiveFilter() {
+ given().accept("application/json")
+ .when()
+ .queryParam("type", 100)
+ .get("/collections")
+ .then().statusCode(200)
+ .and().body("id", contains("empty", "full"));
+ }
+
+ @Test
+ void shouldListWithPrimitiveFilterAndNoResults() {
+ given().accept("application/json")
+ .when()
+ .queryParam("type", 99)
+ .get("/collections")
+ .then().statusCode(200)
+ .and().body("id", empty());
+ }
+
@Test
void shouldListWithFilter() {
given().accept("application/json")
diff --git a/extensions/panache/hibernate-orm-rest-data-panache/deployment/src/test/java/io/quarkus/hibernate/orm/rest/data/panache/deployment/entity/Collection.java b/extensions/panache/hibernate-orm-rest-data-panache/deployment/src/test/java/io/quarkus/hibernate/orm/rest/data/panache/deployment/entity/Collection.java
index fff028b5212d9..138b10db9b5f3 100644
--- a/extensions/panache/hibernate-orm-rest-data-panache/deployment/src/test/java/io/quarkus/hibernate/orm/rest/data/panache/deployment/entity/Collection.java
+++ b/extensions/panache/hibernate-orm-rest-data-panache/deployment/src/test/java/io/quarkus/hibernate/orm/rest/data/panache/deployment/entity/Collection.java
@@ -3,6 +3,7 @@
import java.util.LinkedList;
import java.util.List;
+import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
@@ -18,6 +19,12 @@ public class Collection extends PanacheEntityBase {
public String name;
+ /**
+ * This field is used to reproduce the issue: https://github.com/quarkusio/quarkus/issues/30605
+ */
+ @Column(name = "type", columnDefinition = "int default 100")
+ public int type;
+
@OneToMany(fetch = FetchType.EAGER, mappedBy = "collection")
public List- items = new LinkedList<>();
}
diff --git a/extensions/panache/hibernate-orm-rest-data-panache/deployment/src/test/java/io/quarkus/hibernate/orm/rest/data/panache/deployment/repository/Collection.java b/extensions/panache/hibernate-orm-rest-data-panache/deployment/src/test/java/io/quarkus/hibernate/orm/rest/data/panache/deployment/repository/Collection.java
index 2d11d5adbcf8a..57399f50dca42 100644
--- a/extensions/panache/hibernate-orm-rest-data-panache/deployment/src/test/java/io/quarkus/hibernate/orm/rest/data/panache/deployment/repository/Collection.java
+++ b/extensions/panache/hibernate-orm-rest-data-panache/deployment/src/test/java/io/quarkus/hibernate/orm/rest/data/panache/deployment/repository/Collection.java
@@ -3,6 +3,7 @@
import java.util.LinkedList;
import java.util.List;
+import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
@@ -18,6 +19,12 @@ public class Collection extends PanacheEntityBase {
public String name;
+ /**
+ * This field is used to reproduce the issue: https://github.com/quarkusio/quarkus/issues/30605
+ */
+ @Column(name = "type", columnDefinition = "int default 100")
+ public int type;
+
@OneToMany(fetch = FetchType.EAGER, mappedBy = "collection")
public List
- items = new LinkedList<>();
}
diff --git a/extensions/panache/rest-data-panache/deployment/src/main/java/io/quarkus/rest/data/panache/deployment/methods/ListMethodImplementor.java b/extensions/panache/rest-data-panache/deployment/src/main/java/io/quarkus/rest/data/panache/deployment/methods/ListMethodImplementor.java
index be4de64d9e5c4..066b82c66c855 100644
--- a/extensions/panache/rest-data-panache/deployment/src/main/java/io/quarkus/rest/data/panache/deployment/methods/ListMethodImplementor.java
+++ b/extensions/panache/rest-data-panache/deployment/src/main/java/io/quarkus/rest/data/panache/deployment/methods/ListMethodImplementor.java
@@ -1,11 +1,13 @@
package io.quarkus.rest.data.panache.deployment.methods;
import static io.quarkus.arc.processor.DotNames.BOOLEAN;
+import static io.quarkus.arc.processor.DotNames.BYTE;
import static io.quarkus.arc.processor.DotNames.CHARACTER;
import static io.quarkus.arc.processor.DotNames.DOUBLE;
import static io.quarkus.arc.processor.DotNames.FLOAT;
import static io.quarkus.arc.processor.DotNames.INTEGER;
import static io.quarkus.arc.processor.DotNames.LONG;
+import static io.quarkus.arc.processor.DotNames.SHORT;
import static io.quarkus.arc.processor.DotNames.STRING;
import static io.quarkus.gizmo.MethodDescriptor.ofConstructor;
import static io.quarkus.gizmo.MethodDescriptor.ofMethod;
@@ -15,6 +17,7 @@
import static io.quarkus.rest.data.panache.deployment.utils.SignatureMethodCreator.param;
import static io.quarkus.rest.data.panache.deployment.utils.SignatureMethodCreator.responseType;
import static io.quarkus.rest.data.panache.deployment.utils.SignatureMethodCreator.uniType;
+import static io.quarkus.rest.data.panache.deployment.utils.TypeUtils.primitiveToClass;
import java.util.ArrayList;
import java.util.Collection;
@@ -255,7 +258,8 @@ private Collection getFieldsToQuery(ResourceMe
return resourceMetadata.getFields().entrySet()
.stream()
.filter(e -> isFieldTypeCompatibleForQueryParam(e.getValue()))
- .map(e -> param(e.getKey(), e.getValue().name().toString()))
+ // we need to map primitive types to classes to make the fields nullable
+ .map(e -> param(e.getKey(), primitiveToClass(e.getValue().name().toString())))
.collect(Collectors.toList());
}
@@ -354,9 +358,11 @@ private boolean isFieldTypeCompatibleForQueryParam(Type fieldType) {
|| fieldType.name().equals(BOOLEAN)
|| fieldType.name().equals(CHARACTER)
|| fieldType.name().equals(DOUBLE)
+ || fieldType.name().equals(SHORT)
|| fieldType.name().equals(FLOAT)
|| fieldType.name().equals(INTEGER)
|| fieldType.name().equals(LONG)
+ || fieldType.name().equals(BYTE)
|| fieldType.kind() == Type.Kind.PRIMITIVE;
}
}
diff --git a/extensions/panache/rest-data-panache/deployment/src/main/java/io/quarkus/rest/data/panache/deployment/methods/StandardMethodImplementor.java b/extensions/panache/rest-data-panache/deployment/src/main/java/io/quarkus/rest/data/panache/deployment/methods/StandardMethodImplementor.java
index f7f1e299a2ffa..1af632b140993 100644
--- a/extensions/panache/rest-data-panache/deployment/src/main/java/io/quarkus/rest/data/panache/deployment/methods/StandardMethodImplementor.java
+++ b/extensions/panache/rest-data-panache/deployment/src/main/java/io/quarkus/rest/data/panache/deployment/methods/StandardMethodImplementor.java
@@ -27,7 +27,6 @@
import io.quarkus.gizmo.ClassCreator;
import io.quarkus.gizmo.FieldDescriptor;
import io.quarkus.gizmo.TryBlock;
-import io.quarkus.gizmo.Type;
import io.quarkus.rest.data.panache.RestDataPanacheException;
import io.quarkus.rest.data.panache.deployment.ResourceMetadata;
import io.quarkus.rest.data.panache.deployment.properties.ResourceProperties;
@@ -236,19 +235,6 @@ protected boolean isNotReactivePanache() {
return !capabilities.isPresent(Capability.HIBERNATE_REACTIVE);
}
- public static Type toType(Object object) {
- if (object instanceof Type) {
- return (Type) object;
- } else if (object instanceof String) {
- return Type.classType((String) object);
- } else if (object instanceof Class) {
- return Type.classType((Class>) object);
- }
-
- throw new IllegalArgumentException("Unsupported object of type " + object.getClass()
- + ". Supported types are Type, String and Class");
- }
-
private static Class> toClass(String className) {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
try {
diff --git a/extensions/panache/rest-data-panache/deployment/src/main/java/io/quarkus/rest/data/panache/deployment/utils/SignatureMethodCreator.java b/extensions/panache/rest-data-panache/deployment/src/main/java/io/quarkus/rest/data/panache/deployment/utils/SignatureMethodCreator.java
index 7cf067627531a..b2531ab20cd22 100644
--- a/extensions/panache/rest-data-panache/deployment/src/main/java/io/quarkus/rest/data/panache/deployment/utils/SignatureMethodCreator.java
+++ b/extensions/panache/rest-data-panache/deployment/src/main/java/io/quarkus/rest/data/panache/deployment/utils/SignatureMethodCreator.java
@@ -2,7 +2,7 @@
import static io.quarkus.gizmo.Type.classType;
import static io.quarkus.gizmo.Type.parameterizedType;
-import static io.quarkus.rest.data.panache.deployment.methods.StandardMethodImplementor.toType;
+import static io.quarkus.rest.data.panache.deployment.utils.TypeUtils.toGizmoType;
import java.util.ArrayList;
import java.util.List;
@@ -52,7 +52,7 @@ public static MethodCreator getMethodCreator(String methodName, ClassCreator cla
}
public static Parameter param(String name, Object type) {
- return param(name, type, toType(type));
+ return param(name, type, toGizmoType(type));
}
public static Parameter param(String name, Object clazz, Type type) {
@@ -90,7 +90,7 @@ public static ReturnType uniType(Object... arguments) {
ReturnType returnType = new ReturnType();
Type[] typeArguments = new Type[arguments.length];
for (int index = 0; index < arguments.length; index++) {
- typeArguments[index] = toType(arguments[index]);
+ typeArguments[index] = toGizmoType(arguments[index]);
}
returnType.classType = Uni.class;
diff --git a/extensions/panache/rest-data-panache/deployment/src/main/java/io/quarkus/rest/data/panache/deployment/utils/TypeUtils.java b/extensions/panache/rest-data-panache/deployment/src/main/java/io/quarkus/rest/data/panache/deployment/utils/TypeUtils.java
new file mode 100644
index 0000000000000..0980cd870cc74
--- /dev/null
+++ b/extensions/panache/rest-data-panache/deployment/src/main/java/io/quarkus/rest/data/panache/deployment/utils/TypeUtils.java
@@ -0,0 +1,45 @@
+package io.quarkus.rest.data.panache.deployment.utils;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import io.quarkus.gizmo.Type;
+
+public final class TypeUtils {
+
+ private static final Map PRIMITIVE_TO_CLASS_MAPPING = new HashMap<>();
+
+ static {
+ PRIMITIVE_TO_CLASS_MAPPING.put("int", Integer.class);
+ PRIMITIVE_TO_CLASS_MAPPING.put("byte", Byte.class);
+ PRIMITIVE_TO_CLASS_MAPPING.put("char", Character.class);
+ PRIMITIVE_TO_CLASS_MAPPING.put("short", Short.class);
+ PRIMITIVE_TO_CLASS_MAPPING.put("long", Long.class);
+ PRIMITIVE_TO_CLASS_MAPPING.put("float", Float.class);
+ PRIMITIVE_TO_CLASS_MAPPING.put("double", Double.class);
+ PRIMITIVE_TO_CLASS_MAPPING.put("boolean", Boolean.class);
+ }
+
+ private TypeUtils() {
+
+ }
+
+ public static Object primitiveToClass(String type) {
+ Class> clazz = PRIMITIVE_TO_CLASS_MAPPING.get(type);
+ return clazz != null ? clazz : type;
+ }
+
+ public static Type toGizmoType(Object object) {
+ if (object instanceof Type) {
+ return (Type) object;
+ } else if (object instanceof String) {
+ return Type.classType((String) object);
+ } else if (object instanceof Class) {
+ return Type.classType((Class>) object);
+ }
+
+ throw new IllegalArgumentException("Unsupported object of type " + object.getClass()
+ + ". Supported types are Type, String and Class");
+ }
+
+}
From b89fece02881a35354482900fc2db255d42adb8a Mon Sep 17 00:00:00 2001
From: Jose
Date: Mon, 16 Jan 2023 07:46:27 +0100
Subject: [PATCH 030/250] Add HTTPS port in generated containers by Kubernetes
These changes will add an additional container port HTTPS in the generated manifests:
```yaml
containers:
- image: ...
imagePullPolicy: IfNotPresent
name: kubernetes-kind
ports:
- containerPort: 8080
name: http
protocol: TCP
- containerPort: 8443
name: https
protocol: TCP
```
By default, the Ingress and Route resources will use the "http" port. However, as part of these changes, I've added a new property to select between "https" or "http", or any other that user might have added as part of the configuration. Example:
```
quarkus.kubernetes.ingress.target-port=https
quarkus.openshift.route.target-port=https
```
Finally, note that the https container won't be added for the Knative resources since there seems to be a limitation at Knative side.
Fix https://github.com/quarkusio/quarkus/issues/29999
asd
---
.../asciidoc/deploying-to-kubernetes.adoc | 1 +
.../kind/deployment/KindProcessor.java | 5 +-
.../deployment/AddNodePortDecorator.java | 27 +++-----
.../ApplyOpenshiftRouteConfigurator.java | 5 +-
.../deployment/DevClusterHelper.java | 19 +++---
.../deployment/KnativeProcessor.java | 16 +++--
.../deployment/KubernetesCommonHelper.java | 30 +++++++--
.../deployment/OpenshiftProcessor.java | 13 ++--
.../kubernetes/deployment/RouteConfig.java | 5 +-
.../VanillaKubernetesProcessor.java | 25 +++----
.../http/deployment/VertxHttpProcessor.java | 16 ++++-
.../it/kubernetes/BasicKubernetesTest.java | 10 ++-
.../it/kubernetes/KindWithDefaultsTest.java | 2 +-
.../it/kubernetes/KnativeWithHealthTest.java | 2 +-
...MinikubeWithApplicationPropertiesTest.java | 4 +-
.../KubernetesServiceMappingTest.java | 8 +--
...bernetesWithApplicationPropertiesTest.java | 4 +-
.../KubernetesWithCustomResourcesTest.java | 2 +-
.../KubernetesWithIngressTargetPortTest.java | 67 +++++++++++++++++++
.../KubernetesWithMultiplePortsTest.java | 6 +-
.../KubernetesWithSidecarAndJibTest.java | 2 +-
...MinikubeWithApplicationPropertiesTest.java | 2 +-
.../kubernetes/MinikubeWithDefaultsTest.java | 8 ++-
...penshiftWithApplicationPropertiesTest.java | 2 +-
.../OpenshiftWithRoutePropertiesTest.java | 2 +-
.../it/kubernetes/OpenshiftWithS2iTest.java | 2 +-
...rnetes-with-ingress-target-port.properties | 2 +
27 files changed, 193 insertions(+), 94 deletions(-)
create mode 100644 integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithIngressTargetPortTest.java
create mode 100644 integration-tests/kubernetes/quarkus-standard-way/src/test/resources/kubernetes-with-ingress-target-port.properties
diff --git a/docs/src/main/asciidoc/deploying-to-kubernetes.adoc b/docs/src/main/asciidoc/deploying-to-kubernetes.adoc
index c84510ab47dd6..afeb27b99389a 100644
--- a/docs/src/main/asciidoc/deploying-to-kubernetes.adoc
+++ b/docs/src/main/asciidoc/deploying-to-kubernetes.adoc
@@ -770,6 +770,7 @@ To secure the incoming connections, Kubernetes allows enabling https://kubernete
[source]
----
quarkus.kubernetes.ingress.expose=true
+quarkus.kubernetes.ingress.target-port=https
## Ingress TLS configuration:
quarkus.kubernetes.ingress.tls.my-secret.enabled=true
----
diff --git a/extensions/kubernetes/kind/deployment/src/main/java/io/quarkus/kind/deployment/KindProcessor.java b/extensions/kubernetes/kind/deployment/src/main/java/io/quarkus/kind/deployment/KindProcessor.java
index c9d871cddc1ed..47cba6debd7ba 100644
--- a/extensions/kubernetes/kind/deployment/src/main/java/io/quarkus/kind/deployment/KindProcessor.java
+++ b/extensions/kubernetes/kind/deployment/src/main/java/io/quarkus/kind/deployment/KindProcessor.java
@@ -84,9 +84,8 @@ public void createLabels(KubernetesConfig config, BuildProducer createConfigurators(KubernetesConfig config,
List ports) {
List