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 0daec6e..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
@@ -111,7 +111,7 @@
org.springframework.boot
spring-boot-starter-parent
- 2.7.5
+ 3.1.4
@@ -135,11 +135,22 @@
org.projectlombok
lombok
+ [1.18.30,)
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 {