diff --git a/bom/application/pom.xml b/bom/application/pom.xml
index fb54502ae14b73..3168e48b4a2065 100644
--- a/bom/application/pom.xml
+++ b/bom/application/pom.xml
@@ -47,7 +47,7 @@
2.0
4.0.2
2.8.0
- 3.10.2
+ 3.10.3-SNAPSHOT
4.1.0
4.0.0
4.0.3
diff --git a/extensions/hibernate-validator/deployment/src/test/java/io/quarkus/hibernate/validator/test/config/ConfigMappingInvalidTest.java b/extensions/hibernate-validator/deployment/src/test/java/io/quarkus/hibernate/validator/test/config/ConfigMappingInvalidTest.java
index 696b7a2dc61f93..cedf4a2bc434cc 100644
--- a/extensions/hibernate-validator/deployment/src/test/java/io/quarkus/hibernate/validator/test/config/ConfigMappingInvalidTest.java
+++ b/extensions/hibernate-validator/deployment/src/test/java/io/quarkus/hibernate/validator/test/config/ConfigMappingInvalidTest.java
@@ -1,56 +1,76 @@
package io.quarkus.hibernate.validator.test.config;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.time.Duration;
+import java.time.Period;
import java.util.List;
-
-import jakarta.inject.Inject;
+import java.util.Map;
+import java.util.Optional;
+import java.util.OptionalInt;
+import java.util.function.Consumer;
+
+import jakarta.validation.Constraint;
+import jakarta.validation.ConstraintValidator;
+import jakarta.validation.ConstraintValidatorContext;
+import jakarta.validation.Payload;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.Size;
import org.jboss.shrinkwrap.api.ShrinkWrap;
-import org.jboss.shrinkwrap.api.asset.StringAsset;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import io.quarkus.arc.Unremovable;
+import io.quarkus.runtime.configuration.DurationConverter;
import io.quarkus.test.QuarkusUnitTest;
import io.smallrye.config.ConfigMapping;
import io.smallrye.config.ConfigValidationException;
-import io.smallrye.config.SmallRyeConfig;
+import io.smallrye.config.WithConverter;
+import io.smallrye.config.WithDefault;
+import io.smallrye.config.WithName;
+import io.smallrye.config.WithParentName;
public class ConfigMappingInvalidTest {
@RegisterExtension
- static final QuarkusUnitTest UNIT_TEST = new QuarkusUnitTest().setArchiveProducer(
+ static final QuarkusUnitTest TEST = new QuarkusUnitTest().setArchiveProducer(
() -> ShrinkWrap.create(JavaArchive.class)
- .addAsResource(new StringAsset("validator.server.host=localhost\n" +
- "validator.server.services=redis,postgresql\n" +
- "validator.hierarchy.number=1\n" +
- "validator.repeatable.name=a"), "application.properties"));
-
- @Inject
- SmallRyeConfig config;
+ .addAsResource("application-mappings-validation.properties", "application.properties"))
+ .assertException(new Consumer() {
+ @Override
+ public void accept(final Throwable throwable) {
+ // can't use instanceOf because of different ClassLoaders
+ assertEquals(ConfigValidationException.class.getName(), throwable.getClass().getName());
+ String message = throwable.getMessage();
+ assertTrue(message.contains("validator.server.host must be less than or equal to 3"));
+ assertTrue(message.contains("validator.hierarchy.number must be greater than or equal to 10"));
+ assertTrue(message.contains("validator.repeatable.name size must be between 2"));
+
+ assertTrue(message.contains("cloud.port must be greater than or equal to 8000"));
+ assertTrue(message.contains("cloud.log.days must be less than or equal to 15"));
+ assertTrue(message.contains("cloud.cors.origins[1].port must be greater than or equal to 8000"));
+ assertTrue(message.contains("cloud.info.name size must be between 0 and 3"));
+ assertTrue(message.contains("cloud.info.code must be less than or equal to 3"));
+ assertTrue(message.contains("cloud.info.alias[0] size must be between 0 and 3"));
+ assertTrue(message.contains("cloud.info.admins.root[1].username size must be between 0 and 4"));
+ assertTrue(message.contains("cloud.info.firewall.accepted[1] size must be between 8 and 15"));
+ assertTrue(message.contains("cloud.proxy.timeout must be less than or equal to 10"));
+ assertTrue(message.contains("cloud server is not prod"));
+ }
+ });
@Test
void invalid() {
- assertThrows(ConfigValidationException.class, () -> config.getConfigMapping(Server.class),
- "validator.server.host must be less than or equal to 3");
- }
-
- @Test
- @Disabled("Requires https://github.com/smallrye/smallrye-config/pull/923")
- void invalidHierarchy() {
- assertThrows(ConfigValidationException.class, () -> config.getConfigMapping(Child.class),
- "validator.hierarchy.number must be greater than or equal to 10");
- }
-
- @Test
- void repeatable() {
- assertThrows(ConfigValidationException.class, () -> config.getConfigMapping(Repeatable.class));
+ fail();
}
@Unremovable
@@ -80,4 +100,138 @@ public interface Repeatable {
@Size(min = 2)
String name();
}
+
+ @Unremovable
+ @ConfigMapping(prefix = "cloud")
+ @Prod
+ public interface Cloud {
+ String host();
+
+ @Min(8000)
+ int port();
+
+ @WithConverter(DurationConverter.class)
+ Duration timeout();
+
+ @WithName("io-threads")
+ int threads();
+
+ @WithParentName
+ Map form();
+
+ Optional ssl();
+
+ Optional proxy();
+
+ Optional cors();
+
+ Log log();
+
+ Info info();
+
+ interface Form {
+ String loginPage();
+
+ String errorPage();
+
+ String landingPage();
+
+ Optional cookie();
+
+ @WithDefault("1")
+ List positions();
+ }
+
+ interface Ssl {
+ int port();
+
+ String certificate();
+
+ @WithDefault("TLSv1.3,TLSv1.2")
+ List protocols();
+ }
+
+ interface Proxy {
+ boolean enable();
+
+ @Max(10)
+ int timeout();
+ }
+
+ interface Log {
+ @WithDefault("false")
+ boolean enabled();
+
+ @WithDefault(".log")
+ String suffix();
+
+ @WithDefault("true")
+ boolean rotate();
+
+ @WithDefault("COMMON")
+ Pattern pattern();
+
+ Period period();
+
+ @Max(15)
+ int days();
+
+ enum Pattern {
+ COMMON,
+ SHORT,
+ COMBINED,
+ LONG;
+ }
+ }
+
+ interface Cors {
+ List origins();
+
+ List<@Size(min = 2) String> methods();
+
+ interface Origin {
+ @Size(min = 5)
+ String host();
+
+ @Min(8000)
+ int port();
+ }
+ }
+
+ interface Info {
+ Optional<@Size(max = 3) String> name();
+
+ @Max(3)
+ OptionalInt code();
+
+ Optional> alias();
+
+ Map> admins();
+
+ Map> firewall();
+
+ interface Admin {
+ @Size(max = 4)
+ String username();
+ }
+ }
+ }
+
+ @Target({ ElementType.TYPE_USE, ElementType.FIELD })
+ @Retention(RetentionPolicy.RUNTIME)
+ @Constraint(validatedBy = Prod.Validator.class)
+ public @interface Prod {
+ String message() default "server is not prod";
+
+ Class>[] groups() default {};
+
+ Class extends Payload>[] payload() default {};
+
+ class Validator implements ConstraintValidator {
+ @Override
+ public boolean isValid(final Cloud value, final ConstraintValidatorContext context) {
+ return value.host().equals("prod");
+ }
+ }
+ }
}
diff --git a/extensions/hibernate-validator/deployment/src/test/resources/application-mappings-validation.properties b/extensions/hibernate-validator/deployment/src/test/resources/application-mappings-validation.properties
new file mode 100644
index 00000000000000..a94e71916cc37b
--- /dev/null
+++ b/extensions/hibernate-validator/deployment/src/test/resources/application-mappings-validation.properties
@@ -0,0 +1,34 @@
+validator.server.host=localhost
+validator.server.services=redis,postgresql
+validator.hierarchy.number=1
+validator.repeatable.name=a
+
+cloud.host=localhost
+cloud.port=5000
+cloud.io-threads=200
+cloud.timeout=60s
+cloud.form.error-page=error.html
+cloud.form.landing-page=index.html
+cloud.form.login-page=login.html
+cloud.info.admins.root[0].username=root
+cloud.info.admins.root[1].username=super
+cloud.info.alias=James
+cloud.info.alias[0]=James
+cloud.info.code=007
+cloud.info.firewall.accepted=127.0.0.1,8.8.8
+cloud.info.firewall.accepted[0]=127.0.0.1
+cloud.info.firewall.accepted[1]=8.8.8
+cloud.info.name=Bond
+cloud.log.days=20
+cloud.log.period=P1D
+cloud.proxy.enable=true
+cloud.proxy.timeout=20
+cloud.ssl.certificate=certificate
+cloud.ssl.port=8443
+cloud.cors.methods=GET,POST
+cloud.cors.methods[0]=GET
+cloud.cors.methods[1]=POST
+cloud.cors.origins[0].host=some-server
+cloud.cors.origins[0].port=9000
+cloud.cors.origins[1].host=localhost
+cloud.cors.origins[1].port=1
diff --git a/integration-tests/smallrye-config/src/main/java/io/quarkus/it/smallrye/config/Cloud.java b/integration-tests/smallrye-config/src/main/java/io/quarkus/it/smallrye/config/Cloud.java
deleted file mode 100644
index 74fd78e03b5e54..00000000000000
--- a/integration-tests/smallrye-config/src/main/java/io/quarkus/it/smallrye/config/Cloud.java
+++ /dev/null
@@ -1,136 +0,0 @@
-package io.quarkus.it.smallrye.config;
-
-import java.time.Duration;
-import java.time.Period;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.OptionalInt;
-
-import jakarta.validation.constraints.Max;
-import jakarta.validation.constraints.Min;
-import jakarta.validation.constraints.Size;
-
-import io.quarkus.arc.Unremovable;
-import io.quarkus.runtime.configuration.DurationConverter;
-import io.smallrye.config.ConfigMapping;
-import io.smallrye.config.WithConverter;
-import io.smallrye.config.WithDefault;
-import io.smallrye.config.WithName;
-import io.smallrye.config.WithParentName;
-
-@Unremovable
-@ConfigMapping(prefix = "cloud")
-@Prod
-public interface Cloud {
- String host();
-
- @Min(8000)
- int port();
-
- @WithConverter(DurationConverter.class)
- Duration timeout();
-
- @WithName("io-threads")
- int threads();
-
- @WithParentName
- Map form();
-
- Optional ssl();
-
- Optional proxy();
-
- Optional cors();
-
- Log log();
-
- Info info();
-
- interface Form {
- String loginPage();
-
- String errorPage();
-
- String landingPage();
-
- Optional cookie();
-
- @WithDefault("1")
- List positions();
- }
-
- interface Ssl {
- int port();
-
- String certificate();
-
- @WithDefault("TLSv1.3,TLSv1.2")
- List protocols();
- }
-
- interface Proxy {
- boolean enable();
-
- @Max(10)
- int timeout();
- }
-
- interface Log {
- @WithDefault("false")
- boolean enabled();
-
- @WithDefault(".log")
- String suffix();
-
- @WithDefault("true")
- boolean rotate();
-
- @WithDefault("COMMON")
- Pattern pattern();
-
- Period period();
-
- @Max(15)
- int days();
-
- enum Pattern {
- COMMON,
- SHORT,
- COMBINED,
- LONG;
- }
- }
-
- interface Cors {
- List origins();
-
- List<@Size(min = 2) String> methods();
-
- interface Origin {
- @Size(min = 5)
- String host();
-
- @Min(8000)
- int port();
- }
- }
-
- interface Info {
- Optional<@Size(max = 3) String> name();
-
- @Max(3)
- OptionalInt code();
-
- Optional> alias();
-
- Map> admins();
-
- Map> firewall();
-
- interface Admin {
- @Size(max = 4)
- String username();
- }
- }
-}
diff --git a/integration-tests/smallrye-config/src/main/java/io/quarkus/it/smallrye/config/Prod.java b/integration-tests/smallrye-config/src/main/java/io/quarkus/it/smallrye/config/Prod.java
deleted file mode 100644
index 0387cabd46b58f..00000000000000
--- a/integration-tests/smallrye-config/src/main/java/io/quarkus/it/smallrye/config/Prod.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package io.quarkus.it.smallrye.config;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-import jakarta.validation.Constraint;
-import jakarta.validation.ConstraintValidator;
-import jakarta.validation.ConstraintValidatorContext;
-import jakarta.validation.Payload;
-
-@Target({ ElementType.TYPE_USE, ElementType.FIELD })
-@Retention(RetentionPolicy.RUNTIME)
-@Constraint(validatedBy = Prod.Validator.class)
-public @interface Prod {
- String message() default "server is not prod";
-
- Class>[] groups() default {};
-
- Class extends Payload>[] payload() default {};
-
- class Validator implements ConstraintValidator {
- @Override
- public boolean isValid(final Cloud value, final ConstraintValidatorContext context) {
- return value.host().equals("prod");
- }
- }
-}
diff --git a/integration-tests/smallrye-config/src/main/java/io/quarkus/it/smallrye/config/ServerResource.java b/integration-tests/smallrye-config/src/main/java/io/quarkus/it/smallrye/config/ServerResource.java
index 69205f27a85532..ca507f61583c21 100644
--- a/integration-tests/smallrye-config/src/main/java/io/quarkus/it/smallrye/config/ServerResource.java
+++ b/integration-tests/smallrye-config/src/main/java/io/quarkus/it/smallrye/config/ServerResource.java
@@ -4,24 +4,15 @@
import jakarta.enterprise.inject.Instance;
import jakarta.inject.Inject;
-import jakarta.json.Json;
-import jakarta.json.JsonArrayBuilder;
-import jakarta.json.JsonObjectBuilder;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.core.Response;
-import org.eclipse.microprofile.config.Config;
import org.eclipse.microprofile.config.inject.ConfigProperties;
import org.eclipse.microprofile.config.inject.ConfigProperty;
-import io.smallrye.config.ConfigValidationException;
-import io.smallrye.config.SmallRyeConfig;
-
@Path("/server")
public class ServerResource {
- @Inject
- Config config;
@Inject
Server server;
@Inject
@@ -45,26 +36,6 @@ public Response getServerProperties() {
return Response.ok(serverProperties).build();
}
- @GET
- @Path("/validator/cloud")
- public Response validator() {
- try {
- config.unwrap(SmallRyeConfig.class).getConfigMapping(Cloud.class, "cloud");
- } catch (ConfigValidationException e) {
- JsonArrayBuilder jsonArrayBuilder = Json.createArrayBuilder();
- for (int i = 0; i < e.getProblemCount(); i++) {
- jsonArrayBuilder.add(e.getProblem(i).getMessage());
- }
- JsonObjectBuilder jsonObjectBuilder = Json.createObjectBuilder();
- jsonObjectBuilder.add("errors", jsonArrayBuilder);
- return Response.ok().entity(jsonObjectBuilder.build().toString()).build();
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- return Response.serverError().build();
- }
-
@GET
@Path("/info")
public String info() {
diff --git a/integration-tests/smallrye-config/src/main/resources/application.yaml b/integration-tests/smallrye-config/src/main/resources/application.yaml
index 7da81f0bee2bea..81e3e4e7586939 100644
--- a/integration-tests/smallrye-config/src/main/resources/application.yaml
+++ b/integration-tests/smallrye-config/src/main/resources/application.yaml
@@ -34,55 +34,6 @@ http:
period: P1D
days: 10
-cloud:
- host: localhost
- port: 5000
- timeout: 60s
- io-threads: 200
-
- form:
- login-page: login.html
- error-page: error.html
- landing-page: index.html
-
- ssl:
- port: 8443
- certificate: certificate
-
- cors:
- origins:
- - host: some-server
- port: 9000
- - host: localhost
- port: 1
- methods:
- - GET
- - POST
-
- proxy:
- enable: true
- timeout: 20
-
- log:
- period: P1D
- days: 20
-
- info:
- name: Bond
- code: 007
- alias:
- - James
- admins:
- root:
- -
- username: root
- -
- username: super
- firewall:
- accepted:
- - 127.0.0.1
- - 8.8.8
-
profile:
main:
yaml: main
diff --git a/integration-tests/smallrye-config/src/test/java/io/quarkus/it/smallrye/config/ServerResourceTest.java b/integration-tests/smallrye-config/src/test/java/io/quarkus/it/smallrye/config/ServerResourceTest.java
index 400df4f21f1287..0951ad1e8f5f8f 100644
--- a/integration-tests/smallrye-config/src/test/java/io/quarkus/it/smallrye/config/ServerResourceTest.java
+++ b/integration-tests/smallrye-config/src/test/java/io/quarkus/it/smallrye/config/ServerResourceTest.java
@@ -1,19 +1,13 @@
package io.quarkus.it.smallrye.config;
import static io.restassured.RestAssured.given;
-import static jakarta.ws.rs.core.HttpHeaders.ACCEPT;
-import static jakarta.ws.rs.core.HttpHeaders.CONTENT_TYPE;
-import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON;
import static jakarta.ws.rs.core.Response.Status.OK;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
-import static org.hamcrest.Matchers.hasItem;
-import static org.hamcrest.Matchers.hasSize;
import org.junit.jupiter.api.Test;
import io.quarkus.test.junit.QuarkusTest;
-import io.restassured.http.Header;
@QuarkusTest
class ServerResourceTest {
@@ -75,25 +69,4 @@ void info() {
.header("X-VERSION", "1.2.3.4")
.body(containsString("My application info"));
}
-
- @Test
- void invalid() {
- given()
- .header(new Header(CONTENT_TYPE, APPLICATION_JSON))
- .header(new Header(ACCEPT, APPLICATION_JSON))
- .get("/server/validator/{prefix}", "cloud")
- .then()
- .statusCode(OK.getStatusCode())
- .body("errors", hasSize(10))
- .body("errors", hasItem("cloud.port must be greater than or equal to 8000"))
- .body("errors", hasItem("cloud.log.days must be less than or equal to 15"))
- .body("errors", hasItem("cloud.cors.origins[1].port must be greater than or equal to 8000"))
- .body("errors", hasItem("cloud.info.name size must be between 0 and 3"))
- .body("errors", hasItem("cloud.info.code must be less than or equal to 3"))
- .body("errors", hasItem("cloud.info.alias[0] size must be between 0 and 3"))
- .body("errors", hasItem("cloud.info.admins.root[1].username size must be between 0 and 4"))
- .body("errors", hasItem("cloud.info.firewall.accepted[1] size must be between 8 and 15"))
- .body("errors", hasItem("cloud.proxy.timeout must be less than or equal to 10"))
- .body("errors", hasItem("cloud server is not prod"));
- }
}