From b724b7c358057b9962fe5bd83d6324f3a62b23db Mon Sep 17 00:00:00 2001 From: Henrik Hofmeister Date: Mon, 16 Oct 2023 22:39:41 +0200 Subject: [PATCH 1/4] feat: Adjust to newer spring version and add migration framework --- pom.xml | 16 ++- .../annotation/KapetaEnableMongoDB.java | 4 +- .../spring/mongo/AbstractMongoDBConfig.java | 136 +++++------------- 3 files changed, 51 insertions(+), 105 deletions(-) diff --git a/pom.xml b/pom.xml index 0daec6e..eb49636 100644 --- a/pom.xml +++ b/pom.xml @@ -111,13 +111,13 @@ org.springframework.boot spring-boot-starter-parent - 2.7.5 + 3.1.4 UTF-8 UTF-8 - 19 + 21 @ ${java.version} ${java.version} @@ -139,7 +139,17 @@ com.fasterxml.jackson.core jackson-databind - 2.13.4.2 + 2.15.3 + + + io.mongock + mongock-springboot + 5.3.0 + + + io.mongock + mongodb-springdata-v4-driver + 5.3.0 com.kapeta diff --git a/src/main/java/com/kapeta/spring/annotation/KapetaEnableMongoDB.java b/src/main/java/com/kapeta/spring/annotation/KapetaEnableMongoDB.java index b929264..a40bbce 100644 --- a/src/main/java/com/kapeta/spring/annotation/KapetaEnableMongoDB.java +++ b/src/main/java/com/kapeta/spring/annotation/KapetaEnableMongoDB.java @@ -1,7 +1,7 @@ package com.kapeta.spring.annotation; +import io.mongock.runner.springboot.EnableMongock; import org.springframework.data.mongodb.config.EnableMongoAuditing; - import java.lang.annotation.*; /** @@ -11,12 +11,12 @@ @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited - @EnableMongoAuditing( auditorAwareRef = "mongoAuditor", modifyOnCreate = true, setDates = true ) +@EnableMongock public @interface KapetaEnableMongoDB { } diff --git a/src/main/java/com/kapeta/spring/mongo/AbstractMongoDBConfig.java b/src/main/java/com/kapeta/spring/mongo/AbstractMongoDBConfig.java index 9e16e44..00d0529 100644 --- a/src/main/java/com/kapeta/spring/mongo/AbstractMongoDBConfig.java +++ b/src/main/java/com/kapeta/spring/mongo/AbstractMongoDBConfig.java @@ -3,27 +3,28 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; -import com.kapeta.spring.cluster.KapetaClusterService; -import com.mongodb.*; -import com.mongodb.client.MongoClient; -import com.mongodb.client.MongoClients; -import com.mongodb.client.MongoDatabase; +import com.kapeta.spring.config.providers.KapetaConfigurationProvider; +import com.mongodb.ConnectionString; +import com.mongodb.MongoClientSettings; +import com.mongodb.MongoCredential; import lombok.extern.slf4j.Slf4j; import org.bson.Document; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.mongo.MongoClientSettingsBuilderCustomizer; +import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails; +import org.springframework.boot.autoconfigure.mongo.MongoProperties; +import org.springframework.boot.autoconfigure.mongo.PropertiesMongoConnectionDetails; import org.springframework.context.annotation.Bean; import org.springframework.core.convert.converter.Converter; import org.springframework.data.convert.ReadingConverter; import org.springframework.data.convert.WritingConverter; import org.springframework.data.mongodb.MongoDatabaseFactory; -import org.springframework.data.mongodb.core.MongoTemplate; -import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory; -import org.springframework.data.mongodb.core.convert.*; -import org.springframework.data.mongodb.core.mapping.MongoMappingContext; +import org.springframework.data.mongodb.MongoTransactionManager; +import org.springframework.data.mongodb.core.convert.MongoCustomConversions; import java.util.Arrays; -import java.util.Collections; import java.util.Optional; /** @@ -37,7 +38,7 @@ abstract public class AbstractMongoDBConfig { private static final String PORT_TYPE = "mongodb"; @Autowired - private KapetaClusterService kapetaConfigSource; + private KapetaConfigurationProvider configurationProvider; @Autowired private ObjectMapper objectMapper; @@ -47,92 +48,48 @@ abstract public class AbstractMongoDBConfig { private final String resourceName; - private String databaseName; - - private String dbAuthDB; - protected AbstractMongoDBConfig(String resourceName) { this.resourceName = resourceName; } + @Bean("mongoInfo") + public KapetaConfigurationProvider.ResourceInfo mongoInfo() { + return configurationProvider.getResourceInfo(RESOURCE_TYPE, PORT_TYPE, resourceName); + } @Bean - public MongoClient createClient() { - final KapetaClusterService.ResourceInfo mongoInfo = kapetaConfigSource.getResourceInfo(RESOURCE_TYPE, PORT_TYPE, resourceName); - Optional dbUsername = Optional.ofNullable(mongoInfo.getCredentials().get("username")); - Optional dbPassword = Optional.ofNullable(mongoInfo.getCredentials().get("password")); - - dbAuthDB = String.valueOf(mongoInfo.getOptions().getOrDefault("authdb", "admin")); - databaseName = String.valueOf(mongoInfo.getOptions().getOrDefault("dbName", resourceName)); - - ServerAddress serverAddress = new ServerAddress(mongoInfo.getHost(), Integer.parseInt(mongoInfo.getPort())); - - log.info("Connecting to mongodb server: {}:{} for db: {}", mongoInfo.getHost(), mongoInfo.getPort(), databaseName); - - MongoClientSettings.Builder options = MongoClientSettings.builder() - .writeConcern(WriteConcern.JOURNALED) - .applicationName(applicationName) - .applyToClusterSettings(cluster -> { - cluster.hosts(Collections.singletonList(serverAddress)); - }); - - if (dbUsername.isPresent() && - !dbUsername.get().trim().isEmpty()) { - options.credential( - MongoCredential.createCredential( - dbUsername.get(), - dbAuthDB, - dbPassword.orElse("").toCharArray() - ) - ); - } - - return MongoClients.create(options.build()); + public PropertiesMongoConnectionDetails mongoConnectionDetails(KapetaConfigurationProvider.ResourceInfo mongoInfo) { + String databaseName = String.valueOf(mongoInfo.getOptions().getOrDefault("dbName", resourceName)); + String dbAuthDB = String.valueOf(mongoInfo.getOptions().getOrDefault("authdb", "admin")); + MongoProperties properties = new MongoProperties(); + properties.setDatabase(databaseName); + properties.setHost(mongoInfo.getHost()); + properties.setPort(Integer.valueOf(mongoInfo.getPort())); + properties.setUsername(mongoInfo.getCredentials().get("username")); + properties.setPassword(mongoInfo.getCredentials().getOrDefault("password","").toCharArray()); + properties.setAuthenticationDatabase(dbAuthDB); + properties.setAutoIndexCreation(true); + return new PropertiesMongoConnectionDetails(properties); } @Bean - public MongoDatabaseFactory mongoDbFactory(MongoClient mongoClient) { - final SimpleMongoClientDatabaseFactory simpleMongoDbFactory = new SimpleMongoClientDatabaseFactory(mongoClient, databaseName); - - log.info("Using mongodb database: {}", databaseName); - - return simpleMongoDbFactory; + public MongoClientSettingsBuilderCustomizer customizer() { + return settings -> settings.applicationName(applicationName); } @Bean - public MongoConverter mongoConverter(MongoDatabaseFactory factory) { + public MongoTransactionManager transactionManager(MongoDatabaseFactory dbFactory) { + return new MongoTransactionManager(dbFactory); + } - DbRefResolver dbRefResolver = new DefaultDbRefResolver(factory); + @Bean + public MongoCustomConversions objectNodeConverters() { - MongoCustomConversions conversions = new MongoCustomConversions(Arrays.asList( + return new MongoCustomConversions(Arrays.asList( new MongoToJackson(), new JacksonToMongo() )); - - MongoMappingContext mappingContext = new MongoMappingContext(); - mappingContext.setSimpleTypeHolder(conversions.getSimpleTypeHolder()); - mappingContext.afterPropertiesSet(); - - MappingMongoConverter converter = new MappingMongoConverter(dbRefResolver, mappingContext); - - converter.setCustomConversions(conversions); - converter.afterPropertiesSet(); - - return converter; - } - - @Bean - public MongoTemplate mongoTemplate(MongoDatabaseFactory factory, MongoConverter mongoConverter) { - return new MongoTemplate(factory, mongoConverter); } - @Bean("adminDb") - public MongoDatabase adminDb(MongoTemplate template) { - final MongoDatabase adminDb = template.getMongoDatabaseFactory().getMongoDatabase(dbAuthDB); - - enableSharding(adminDb, template); - - return adminDb; - } @Bean("mongoAuditor") public MongoAuditor mongoAuditor() { @@ -140,27 +97,6 @@ public MongoAuditor mongoAuditor() { } - private void enableSharding(MongoDatabase adminDb, MongoTemplate mongoTemplate) { - - try { - - BasicDBObject enableShardingCmd = new BasicDBObject("enableSharding", mongoTemplate.getDb().getName()); - adminDb.runCommand(enableShardingCmd); - } catch (MongoCommandException ex) { - if (ex.getErrorCode() == -1) { - log.info("Sharding already enabled for db: {}", mongoTemplate.getDb().getName()); - return; - } - - if (ex.getErrorCode() == 59) { - log.warn("Command not found - not connected to cluster (mongos)? [Error: {}] Continuing...", ex.getErrorMessage()); - return; - } - - throw ex; - } - } - @ReadingConverter private class MongoToJackson implements Converter { From e59b722e3f3e89d1c26c6adcec1ae02e0af1b368 Mon Sep 17 00:00:00 2001 From: Henrik Hofmeister Date: Tue, 17 Oct 2023 00:27:05 +0200 Subject: [PATCH 2/4] add license and ensure lombok version that can do java 21 --- LICENSE | 21 +++++++++++++++++++++ pom.xml | 1 + 2 files changed, 22 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..9683263 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Kapeta + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/pom.xml b/pom.xml index eb49636..a49587d 100644 --- a/pom.xml +++ b/pom.xml @@ -135,6 +135,7 @@ org.projectlombok lombok + [1.18.30,) com.fasterxml.jackson.core From 8d348f96aa5700135a8f4e66dd414103d7cdbd8a Mon Sep 17 00:00:00 2001 From: Henrik Hofmeister Date: Tue, 17 Oct 2023 11:18:04 +0200 Subject: [PATCH 3/4] use java 19 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a49587d..ed483f6 100644 --- a/pom.xml +++ b/pom.xml @@ -117,7 +117,7 @@ UTF-8 UTF-8 - 21 + 19 @ ${java.version} ${java.version} From e3dc1f5c10cadc8c04f003009383b84ff81b9b52 Mon Sep 17 00:00:00 2001 From: Henrik Hofmeister Date: Tue, 17 Oct 2023 11:20:01 +0200 Subject: [PATCH 4/4] bump --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ed483f6..376f380 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.kapeta nosql-mongodb - 0.0.7 + 0.1.0 ${project.groupId}:${project.artifactId} MongoDB support for Kapeta Spring Boot SDK