Skip to content

Commit

Permalink
Merge pull request #46070 from mcruzdev/config-mongodb-client
Browse files Browse the repository at this point in the history
Convert mongodb-client to use @ConfigMapping
  • Loading branch information
gsmet authored Feb 4, 2025
2 parents d656dc3 + a620f6a commit 28d1816
Show file tree
Hide file tree
Showing 17 changed files with 254 additions and 249 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ private String parseChangeLog(String changeLog) {
public Liquibase createLiquibase() {
try (ResourceAccessor resourceAccessor = resolveResourceAccessor()) {
String parsedChangeLog = parseChangeLog(liquibaseMongodbBuildTimeConfig.changeLog());
String connectionString = this.mongoClientConfig.connectionString.orElse("mongodb://localhost:27017");
String connectionString = this.mongoClientConfig.connectionString().orElse("mongodb://localhost:27017");

// Every MongoDB client configuration must be added to the connection string, we didn't add all as it would be too much to support.
// For reference, all connections string options can be found here: https://www.mongodb.com/docs/manual/reference/connection-string/#connection-string-options.
Expand All @@ -93,31 +93,31 @@ public Liquibase createLiquibase() {
if (!matcher.matches() || matcher.group("db") == null || matcher.group("db").isEmpty()) {
connectionString = matcher.replaceFirst(
"${prefix}${hosts}/"
+ this.mongoClientConfig.database
+ this.mongoClientConfig.database()
.orElseThrow(() -> new IllegalArgumentException("Config property " +
"'quarkus.mongodb.database' must be defined when no database exist in the connection string"))
+ "${options}");
}
if (mongoClientConfig.credentials.authSource.isPresent()) {
if (mongoClientConfig.credentials().authSource().isPresent()) {
boolean alreadyHasQueryParams = connectionString.contains("?");
connectionString += (alreadyHasQueryParams ? "&" : "?") + "authSource="
+ mongoClientConfig.credentials.authSource.get();
+ mongoClientConfig.credentials().authSource().get();
}
if (mongoClientConfig.credentials.authMechanism.isPresent()) {
if (mongoClientConfig.credentials().authMechanism().isPresent()) {
boolean alreadyHasQueryParams = connectionString.contains("?");
connectionString += (alreadyHasQueryParams ? "&" : "?") + "authMechanism="
+ mongoClientConfig.credentials.authMechanism.get();
+ mongoClientConfig.credentials().authMechanism().get();
}
if (!mongoClientConfig.credentials.authMechanismProperties.isEmpty()) {
if (!mongoClientConfig.credentials().authMechanismProperties().isEmpty()) {
boolean alreadyHasQueryParams = connectionString.contains("?");
connectionString += (alreadyHasQueryParams ? "&" : "?") + "authMechanismProperties="
+ mongoClientConfig.credentials.authMechanismProperties.entrySet().stream()
+ mongoClientConfig.credentials().authMechanismProperties().entrySet().stream()
.map(prop -> prop.getKey() + ":" + prop.getValue()).collect(Collectors.joining(","));
}

Database database = DatabaseFactory.getInstance().openDatabase(connectionString,
this.mongoClientConfig.credentials.username.orElse(null),
this.mongoClientConfig.credentials.password.orElse(null),
this.mongoClientConfig.credentials().username().orElse(null),
this.mongoClientConfig.credentials().password().orElse(null),
null, resourceAccessor);

if (database != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public Supplier<LiquibaseMongodbFactory> liquibaseSupplier(LiquibaseMongodbConfi
return new Supplier<LiquibaseMongodbFactory>() {
@Override
public LiquibaseMongodbFactory get() {
return new LiquibaseMongodbFactory(config, buildTimeConfig, mongodbConfig.defaultMongoClientConfig);
return new LiquibaseMongodbFactory(config, buildTimeConfig, mongodbConfig.defaultMongoClientConfig());
}
};
}
Expand Down
3 changes: 0 additions & 3 deletions extensions/mongodb-client/deployment/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,6 @@
<version>${project.version}</version>
</path>
</annotationProcessorPaths>
<compilerArgs>
<arg>-AlegacyConfigRoot=true</arg>
</compilerArgs>
</configuration>
</execution>
</executions>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@

import io.quarkus.runtime.annotations.ConfigDocMapKey;
import io.quarkus.runtime.annotations.ConfigGroup;
import io.quarkus.runtime.annotations.ConfigItem;
import io.smallrye.config.WithDefault;

@ConfigGroup
public class DevServicesBuildTimeConfig {
public interface DevServicesBuildTimeConfig {

/**
* If DevServices has been explicitly enabled or disabled. DevServices is generally enabled
Expand All @@ -17,36 +17,31 @@ public class DevServicesBuildTimeConfig {
* When DevServices is enabled Quarkus will attempt to automatically configure and start
* a database when running in Dev or Test mode.
*/
@ConfigItem
public Optional<Boolean> enabled = Optional.empty();
Optional<Boolean> enabled();

/**
* The container image name to use, for container based DevServices providers.
*/
@ConfigItem
public Optional<String> imageName;
Optional<String> imageName();

/**
* Optional fixed port the dev service will listen to.
* <p>
* If not defined, the port will be chosen randomly.
*/
@ConfigItem
public Optional<Integer> port;
Optional<Integer> port();

/**
* Generic properties that are added to the connection URL.
*/
@ConfigItem
@ConfigDocMapKey("property-key")
public Map<String, String> properties;
Map<String, String> properties();

/**
* Environment variables that are passed to the container.
*/
@ConfigItem
@ConfigDocMapKey("environment-variable-name")
public Map<String, String> containerEnv;
Map<String, String> containerEnv();

/**
* Indicates if the MongoDB server managed by Quarkus Dev Services is shared.
Expand All @@ -59,8 +54,8 @@ public class DevServicesBuildTimeConfig {
* <p>
* Container sharing is only used in dev mode.
*/
@ConfigItem(defaultValue = "true")
public boolean shared;
@WithDefault("true")
boolean shared();

/**
* The value of the {@code quarkus-dev-service-mongodb} label attached to the started container.
Expand All @@ -71,7 +66,7 @@ public class DevServicesBuildTimeConfig {
* starts a new container with the {@code quarkus-dev-service-mongodb} label set to the specified value.
* <p>
*/
@ConfigItem(defaultValue = "mongodb")
public String serviceName;
@WithDefault("mongodb")
String serviceName();

}
Original file line number Diff line number Diff line change
Expand Up @@ -247,12 +247,12 @@ private CapturedProperties captureProperties(String connectionName, MongoClientB
String connectionString = ConfigProvider.getConfig().getOptionalValue(configPrefix + "connection-string", String.class)
.orElse(null);
//TODO: update for multiple connections
DevServicesBuildTimeConfig devServicesConfig = mongoClientBuildTimeConfig.devservices;
boolean devServicesEnabled = devServicesConfig.enabled.orElse(true);
DevServicesBuildTimeConfig devServicesConfig = mongoClientBuildTimeConfig.devservices();
boolean devServicesEnabled = devServicesConfig.enabled().orElse(true);
return new CapturedProperties(databaseName, connectionString, devServicesEnabled,
devServicesConfig.imageName.orElseGet(() -> ConfigureUtil.getDefaultImageNameFor("mongo")),
devServicesConfig.port.orElse(null), devServicesConfig.properties, devServicesConfig.containerEnv,
devServicesConfig.shared, devServicesConfig.serviceName);
devServicesConfig.imageName().orElseGet(() -> ConfigureUtil.getDefaultImageNameFor("mongo")),
devServicesConfig.port().orElse(null), devServicesConfig.properties(), devServicesConfig.containerEnv(),
devServicesConfig.shared(), devServicesConfig.serviceName());
}

private record CapturedProperties(String database, String connectionString, boolean devServicesEnabled,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,42 +1,48 @@
package io.quarkus.mongodb.deployment;

import io.quarkus.runtime.annotations.ConfigDocSection;
import io.quarkus.runtime.annotations.ConfigItem;
import io.quarkus.runtime.annotations.ConfigPhase;
import io.quarkus.runtime.annotations.ConfigRoot;
import io.smallrye.config.ConfigMapping;
import io.smallrye.config.WithDefault;
import io.smallrye.config.WithName;

@ConfigRoot(name = "mongodb", phase = ConfigPhase.BUILD_TIME)
public class MongoClientBuildTimeConfig {
@ConfigMapping(prefix = "quarkus.mongodb")
@ConfigRoot(phase = ConfigPhase.BUILD_TIME)
public interface MongoClientBuildTimeConfig {
/**
* Whether a health check is published in case the smallrye-health extension is present.
*/
@ConfigItem(name = "health.enabled", defaultValue = "true")
public boolean healthEnabled;
@WithDefault("true")
@WithName("health.enabled")
boolean healthEnabled();

/**
* Whether metrics are published in case a metrics extension is present.
*/
@ConfigItem(name = "metrics.enabled")
public boolean metricsEnabled;
@WithName("metrics.enabled")
@WithDefault("false")
boolean metricsEnabled();

/**
* If set to true, the default clients will always be created even if there are no injection points that use them
*/
@ConfigItem(name = "force-default-clients")
public boolean forceDefaultClients;
@WithName("force-default-clients")
@WithDefault("false")
boolean forceDefaultClients();

/**
* Whether or not tracing spans of driver commands are sent in case the quarkus-opentelemetry extension is present.
* Whether tracing spans of driver commands are sent in case the quarkus-opentelemetry extension is present.
*/
@ConfigItem(name = "tracing.enabled")
public boolean tracingEnabled;
@WithName("tracing.enabled")
@WithDefault("false")
boolean tracingEnabled();

/**
* Dev Services.
* <p>
* Dev Services allows Quarkus to automatically start MongoDB in dev and test mode.
*/
@ConfigItem
@ConfigDocSection(generated = true)
public DevServicesBuildTimeConfig devservices;
DevServicesBuildTimeConfig devservices();
}
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ AdditionalIndexedClassesBuildItem includeDnsTypesToIndex() {

@BuildStep
AdditionalIndexedClassesBuildItem includeMongoCommandListener(MongoClientBuildTimeConfig buildTimeConfig) {
if (buildTimeConfig.tracingEnabled) {
if (buildTimeConfig.tracingEnabled()) {
return new AdditionalIndexedClassesBuildItem(
MongoTracingCommandListener.class.getName(),
MongoReactiveContextProvider.class.getName());
Expand All @@ -130,7 +130,7 @@ void includeMongoCommandMetricListener(
BuildProducer<AdditionalIndexedClassesBuildItem> additionalIndexedClasses,
MongoClientBuildTimeConfig buildTimeConfig,
Optional<MetricsCapabilityBuildItem> metricsCapability) {
if (!buildTimeConfig.metricsEnabled) {
if (!buildTimeConfig.metricsEnabled()) {
return;
}
boolean withMicrometer = metricsCapability.map(cap -> cap.metricsSupported(MetricsFactory.MICROMETER))
Expand Down Expand Up @@ -259,7 +259,7 @@ MongoConnectionPoolListenerBuildItem setupMetrics(

// Construction of MongoClient isn't compatible with the MetricsFactoryConsumer pattern.
// Use a supplier to defer construction of the pool listener for the supported metrics system
if (buildTimeConfig.metricsEnabled && metricsCapability.isPresent()) {
if (buildTimeConfig.metricsEnabled() && metricsCapability.isPresent()) {
if (metricsCapability.get().metricsSupported(MetricsFactory.MICROMETER)) {
return new MongoConnectionPoolListenerBuildItem(recorder.createMicrometerConnectionPoolListener());
} else {
Expand Down Expand Up @@ -347,7 +347,7 @@ void generateClientBeans(MongoClientRecorder recorder,

boolean createDefaultBlockingMongoClient = false;
boolean createDefaultReactiveMongoClient = false;
if (makeUnremovable || mongoClientBuildTimeConfig.forceDefaultClients) {
if (makeUnremovable || mongoClientBuildTimeConfig.forceDefaultClients()) {
// all clients are expected to exist in this case
createDefaultBlockingMongoClient = true;
createDefaultReactiveMongoClient = true;
Expand All @@ -369,12 +369,12 @@ void generateClientBeans(MongoClientRecorder recorder,

if (createDefaultBlockingMongoClient) {
syntheticBeanBuildItemBuildProducer.produce(createBlockingSyntheticBean(recorder, mongodbConfig,
makeUnremovable || mongoClientBuildTimeConfig.forceDefaultClients,
makeUnremovable || mongoClientBuildTimeConfig.forceDefaultClients(),
MongoClientBeanUtil.DEFAULT_MONGOCLIENT_NAME, false));
}
if (createDefaultReactiveMongoClient) {
syntheticBeanBuildItemBuildProducer.produce(createReactiveSyntheticBean(recorder, mongodbConfig,
makeUnremovable || mongoClientBuildTimeConfig.forceDefaultClients,
makeUnremovable || mongoClientBuildTimeConfig.forceDefaultClients(),
MongoClientBeanUtil.DEFAULT_MONGOCLIENT_NAME, false));
}

Expand Down Expand Up @@ -471,7 +471,7 @@ MongoUnremovableClientsBuildItem unremovable(@SuppressWarnings("unused") BuildPr
@BuildStep
HealthBuildItem addHealthCheck(MongoClientBuildTimeConfig buildTimeConfig) {
return new HealthBuildItem("io.quarkus.mongodb.health.MongoHealthCheck",
buildTimeConfig.healthEnabled);
buildTimeConfig.healthEnabled());
}

@BuildStep
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import io.quarkus.deployment.builditem.AdditionalIndexedClassesBuildItem;
import io.quarkus.deployment.metrics.MetricsCapabilityBuildItem;
import io.quarkus.runtime.metrics.MetricsFactory;
import io.smallrye.config.SmallRyeConfigBuilder;

class MongoClientProcessorTest {
private final MongoClientProcessor buildStep = new MongoClientProcessor();
Expand Down Expand Up @@ -51,9 +52,34 @@ private static Optional<MetricsCapabilityBuildItem> capability(boolean metricsEn
}

private static MongoClientBuildTimeConfig config(boolean metricsEnabled) {
MongoClientBuildTimeConfig buildTimeConfig = new MongoClientBuildTimeConfig();
buildTimeConfig.metricsEnabled = metricsEnabled;
return buildTimeConfig;
return new MongoClientBuildTimeConfig() {
@Override
public boolean healthEnabled() {
return true;
}

@Override
public boolean metricsEnabled() {
return metricsEnabled;
}

@Override
public boolean forceDefaultClients() {
return false;
}

@Override
public boolean tracingEnabled() {
return false;
}

@Override
public DevServicesBuildTimeConfig devservices() {
return new SmallRyeConfigBuilder().addDiscoveredConverters()
.withMapping(DevServicesBuildTimeConfig.class)
.build().getConfigMapping(DevServicesBuildTimeConfig.class);
}
};
}

}
3 changes: 0 additions & 3 deletions extensions/mongodb-client/runtime/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,6 @@
<version>${project.version}</version>
</path>
</annotationProcessorPaths>
<compilerArgs>
<arg>-AlegacyConfigRoot=true</arg>
</compilerArgs>
</configuration>
</execution>
</executions>
Expand Down
Loading

0 comments on commit 28d1816

Please sign in to comment.