Skip to content

Commit 76a13ca

Browse files
authored
feat: Adjust to newer spring version and add migration framework (#3)
1 parent a666214 commit 76a13ca

File tree

4 files changed

+73
-105
lines changed

4 files changed

+73
-105
lines changed

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2023 Kapeta
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

pom.xml

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>com.kapeta</groupId>
88
<artifactId>nosql-mongodb</artifactId>
9-
<version>0.0.7</version>
9+
<version>0.1.0</version>
1010

1111
<name>${project.groupId}:${project.artifactId}</name>
1212
<description>MongoDB support for Kapeta Spring Boot SDK</description>
@@ -111,7 +111,7 @@
111111
<parent>
112112
<groupId>org.springframework.boot</groupId>
113113
<artifactId>spring-boot-starter-parent</artifactId>
114-
<version>2.7.5</version>
114+
<version>3.1.4</version>
115115
</parent>
116116

117117
<properties>
@@ -135,11 +135,22 @@
135135
<dependency>
136136
<groupId>org.projectlombok</groupId>
137137
<artifactId>lombok</artifactId>
138+
<version>[1.18.30,)</version>
138139
</dependency>
139140
<dependency>
140141
<groupId>com.fasterxml.jackson.core</groupId>
141142
<artifactId>jackson-databind</artifactId>
142-
<version>2.13.4.2</version>
143+
<version>2.15.3</version>
144+
</dependency>
145+
<dependency>
146+
<groupId>io.mongock</groupId>
147+
<artifactId>mongock-springboot</artifactId>
148+
<version>5.3.0</version>
149+
</dependency>
150+
<dependency>
151+
<groupId>io.mongock</groupId>
152+
<artifactId>mongodb-springdata-v4-driver</artifactId>
153+
<version>5.3.0</version>
143154
</dependency>
144155
<dependency>
145156
<groupId>com.kapeta</groupId>
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.kapeta.spring.annotation;
22

3+
import io.mongock.runner.springboot.EnableMongock;
34
import org.springframework.data.mongodb.config.EnableMongoAuditing;
4-
55
import java.lang.annotation.*;
66

77
/**
@@ -11,12 +11,12 @@
1111
@Retention(RetentionPolicy.RUNTIME)
1212
@Documented
1313
@Inherited
14-
1514
@EnableMongoAuditing(
1615
auditorAwareRef = "mongoAuditor",
1716
modifyOnCreate = true,
1817
setDates = true
1918
)
19+
@EnableMongock
2020
public @interface KapetaEnableMongoDB {
2121

2222
}

src/main/java/com/kapeta/spring/mongo/AbstractMongoDBConfig.java

Lines changed: 36 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,28 @@
33

44
import com.fasterxml.jackson.databind.ObjectMapper;
55
import com.fasterxml.jackson.databind.node.ObjectNode;
6-
import com.kapeta.spring.cluster.KapetaClusterService;
7-
import com.mongodb.*;
8-
import com.mongodb.client.MongoClient;
9-
import com.mongodb.client.MongoClients;
10-
import com.mongodb.client.MongoDatabase;
6+
import com.kapeta.spring.config.providers.KapetaConfigurationProvider;
7+
import com.mongodb.ConnectionString;
8+
import com.mongodb.MongoClientSettings;
9+
import com.mongodb.MongoCredential;
1110
import lombok.extern.slf4j.Slf4j;
1211
import org.bson.Document;
1312
import org.springframework.beans.factory.annotation.Autowired;
1413
import org.springframework.beans.factory.annotation.Value;
14+
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
15+
import org.springframework.boot.autoconfigure.mongo.MongoClientSettingsBuilderCustomizer;
16+
import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails;
17+
import org.springframework.boot.autoconfigure.mongo.MongoProperties;
18+
import org.springframework.boot.autoconfigure.mongo.PropertiesMongoConnectionDetails;
1519
import org.springframework.context.annotation.Bean;
1620
import org.springframework.core.convert.converter.Converter;
1721
import org.springframework.data.convert.ReadingConverter;
1822
import org.springframework.data.convert.WritingConverter;
1923
import org.springframework.data.mongodb.MongoDatabaseFactory;
20-
import org.springframework.data.mongodb.core.MongoTemplate;
21-
import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory;
22-
import org.springframework.data.mongodb.core.convert.*;
23-
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
24+
import org.springframework.data.mongodb.MongoTransactionManager;
25+
import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
2426

2527
import java.util.Arrays;
26-
import java.util.Collections;
2728
import java.util.Optional;
2829

2930
/**
@@ -37,7 +38,7 @@ abstract public class AbstractMongoDBConfig {
3738
private static final String PORT_TYPE = "mongodb";
3839

3940
@Autowired
40-
private KapetaClusterService kapetaConfigSource;
41+
private KapetaConfigurationProvider configurationProvider;
4142

4243
@Autowired
4344
private ObjectMapper objectMapper;
@@ -47,120 +48,55 @@ abstract public class AbstractMongoDBConfig {
4748

4849
private final String resourceName;
4950

50-
private String databaseName;
51-
52-
private String dbAuthDB;
53-
5451
protected AbstractMongoDBConfig(String resourceName) {
5552
this.resourceName = resourceName;
5653
}
5754

55+
@Bean("mongoInfo")
56+
public KapetaConfigurationProvider.ResourceInfo mongoInfo() {
57+
return configurationProvider.getResourceInfo(RESOURCE_TYPE, PORT_TYPE, resourceName);
58+
}
5859
@Bean
59-
public MongoClient createClient() {
60-
final KapetaClusterService.ResourceInfo mongoInfo = kapetaConfigSource.getResourceInfo(RESOURCE_TYPE, PORT_TYPE, resourceName);
61-
Optional<String> dbUsername = Optional.ofNullable(mongoInfo.getCredentials().get("username"));
62-
Optional<String> dbPassword = Optional.ofNullable(mongoInfo.getCredentials().get("password"));
63-
64-
dbAuthDB = String.valueOf(mongoInfo.getOptions().getOrDefault("authdb", "admin"));
65-
databaseName = String.valueOf(mongoInfo.getOptions().getOrDefault("dbName", resourceName));
66-
67-
ServerAddress serverAddress = new ServerAddress(mongoInfo.getHost(), Integer.parseInt(mongoInfo.getPort()));
68-
69-
log.info("Connecting to mongodb server: {}:{} for db: {}", mongoInfo.getHost(), mongoInfo.getPort(), databaseName);
70-
71-
MongoClientSettings.Builder options = MongoClientSettings.builder()
72-
.writeConcern(WriteConcern.JOURNALED)
73-
.applicationName(applicationName)
74-
.applyToClusterSettings(cluster -> {
75-
cluster.hosts(Collections.singletonList(serverAddress));
76-
});
77-
78-
if (dbUsername.isPresent() &&
79-
!dbUsername.get().trim().isEmpty()) {
80-
options.credential(
81-
MongoCredential.createCredential(
82-
dbUsername.get(),
83-
dbAuthDB,
84-
dbPassword.orElse("").toCharArray()
85-
)
86-
);
87-
}
88-
89-
return MongoClients.create(options.build());
60+
public PropertiesMongoConnectionDetails mongoConnectionDetails(KapetaConfigurationProvider.ResourceInfo mongoInfo) {
61+
String databaseName = String.valueOf(mongoInfo.getOptions().getOrDefault("dbName", resourceName));
62+
String dbAuthDB = String.valueOf(mongoInfo.getOptions().getOrDefault("authdb", "admin"));
63+
MongoProperties properties = new MongoProperties();
64+
properties.setDatabase(databaseName);
65+
properties.setHost(mongoInfo.getHost());
66+
properties.setPort(Integer.valueOf(mongoInfo.getPort()));
67+
properties.setUsername(mongoInfo.getCredentials().get("username"));
68+
properties.setPassword(mongoInfo.getCredentials().getOrDefault("password","").toCharArray());
69+
properties.setAuthenticationDatabase(dbAuthDB);
70+
properties.setAutoIndexCreation(true);
71+
return new PropertiesMongoConnectionDetails(properties);
9072
}
9173

9274
@Bean
93-
public MongoDatabaseFactory mongoDbFactory(MongoClient mongoClient) {
94-
final SimpleMongoClientDatabaseFactory simpleMongoDbFactory = new SimpleMongoClientDatabaseFactory(mongoClient, databaseName);
95-
96-
log.info("Using mongodb database: {}", databaseName);
97-
98-
return simpleMongoDbFactory;
75+
public MongoClientSettingsBuilderCustomizer customizer() {
76+
return settings -> settings.applicationName(applicationName);
9977
}
10078

10179
@Bean
102-
public MongoConverter mongoConverter(MongoDatabaseFactory factory) {
80+
public MongoTransactionManager transactionManager(MongoDatabaseFactory dbFactory) {
81+
return new MongoTransactionManager(dbFactory);
82+
}
10383

104-
DbRefResolver dbRefResolver = new DefaultDbRefResolver(factory);
84+
@Bean
85+
public MongoCustomConversions objectNodeConverters() {
10586

106-
MongoCustomConversions conversions = new MongoCustomConversions(Arrays.asList(
87+
return new MongoCustomConversions(Arrays.asList(
10788
new MongoToJackson(),
10889
new JacksonToMongo()
10990
));
110-
111-
MongoMappingContext mappingContext = new MongoMappingContext();
112-
mappingContext.setSimpleTypeHolder(conversions.getSimpleTypeHolder());
113-
mappingContext.afterPropertiesSet();
114-
115-
MappingMongoConverter converter = new MappingMongoConverter(dbRefResolver, mappingContext);
116-
117-
converter.setCustomConversions(conversions);
118-
converter.afterPropertiesSet();
119-
120-
return converter;
121-
}
122-
123-
@Bean
124-
public MongoTemplate mongoTemplate(MongoDatabaseFactory factory, MongoConverter mongoConverter) {
125-
return new MongoTemplate(factory, mongoConverter);
12691
}
12792

128-
@Bean("adminDb")
129-
public MongoDatabase adminDb(MongoTemplate template) {
130-
final MongoDatabase adminDb = template.getMongoDatabaseFactory().getMongoDatabase(dbAuthDB);
131-
132-
enableSharding(adminDb, template);
133-
134-
return adminDb;
135-
}
13693

13794
@Bean("mongoAuditor")
13895
public MongoAuditor mongoAuditor() {
13996
return new MongoAuditor();
14097
}
14198

14299

143-
private void enableSharding(MongoDatabase adminDb, MongoTemplate mongoTemplate) {
144-
145-
try {
146-
147-
BasicDBObject enableShardingCmd = new BasicDBObject("enableSharding", mongoTemplate.getDb().getName());
148-
adminDb.runCommand(enableShardingCmd);
149-
} catch (MongoCommandException ex) {
150-
if (ex.getErrorCode() == -1) {
151-
log.info("Sharding already enabled for db: {}", mongoTemplate.getDb().getName());
152-
return;
153-
}
154-
155-
if (ex.getErrorCode() == 59) {
156-
log.warn("Command not found - not connected to cluster (mongos)? [Error: {}] Continuing...", ex.getErrorMessage());
157-
return;
158-
}
159-
160-
throw ex;
161-
}
162-
}
163-
164100
@ReadingConverter
165101
private class MongoToJackson implements Converter<Document, ObjectNode> {
166102

0 commit comments

Comments
 (0)